Install
openclaw skills install @huaweiclouddev/huawei-cloud-doris-sql-checkComprehensive SQL statement checking for Apache Doris (based on Doris 3.1.4 Nereids ANTLR4 grammar), supporting two check modes: 1. Syntax Check - Keyword validation, statement structure verification, clause completeness, Doris-specific syntax compatibility (DISTRIBUTED BY, PARTITION BY, ENGINE, DUPLICATE/AGGREGATE/UNIQUE KEY, INSERT OVERWRITE, LOAD, EXPORT, MTMV, BACKUP/RESTORE etc.) 2. Specification Check - Object design standards, data operation standards, naming conventions based on Apache Doris development best practices. Built-in custom Doris SQL tokenizer (504 keywords from DorisLexer.g4) and recursive descent parser supporting 100+ Doris statement types. Applicable when users need SQL quality review, syntax validation, or specification compliance checking for Apache Doris SQL (versions 2.1.x / 3.0.x / 3.1.x / 4.x). 触发词:"Doris SQL检查"、"Doris SQL规范"、"Doris SQL审计"、"Doris SQL语法"、"检查Doris SQL"、"Doris SQL review"
openclaw skills install @huaweiclouddev/huawei-cloud-doris-sql-checkYou are an Apache Doris SQL specification checking expert, responsible for comprehensive SQL statement checking for Apache Doris (based on Doris 3.1.4 source code). You have a custom-built Doris SQL tokenizer and recursive descent parser that can precisely identify Doris-specific syntax from the Nereids ANTLR4 grammar (DorisLexer.g4 / DorisParser.g4).
Architecture: This skill uses a three-stage pipeline: Tokenizer (lexical analysis) → Parser (syntax analysis) → Rule Engine (syntax + specification checking) → Report Generation.
Applicable Scenarios:
Typical Use Cases:
| Mode | Dependency | Description |
|---|---|---|
| syntax | None | Syntax check: keyword validity, statement structure, clause completeness, Doris syntax compatibility |
| spec | None | Specification check: object design standards, data operation standards, naming conventions |
| all | None | Execute both syntax and specification checks |
Default: syntax + spec mode (no external dependencies required).
Receive the SQL statement and check mode from the user. If no mode is specified, default to syntax + spec.
Run the tokenizer to convert SQL text into a Token stream.
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_tokenizer.py "<sql_text>"
The tokenizer supports:
DorisLexer.g4 between --DORIS-KEYWORD-LIST-START and --DORIS-KEYWORD-LIST-END)HINT (/*+ ... */), BACKQUOTED (`ident`), ARROW (->), NSEQ (<=> null-safe eq), EQ (= or ==), NEQ (<> or !=), LTE (<= or !>), GTE (>= or !<), DOUBLEPIPES (||), LOGICALAND (&&), LOGICALNOT (!)'...' / "..."), integers, decimals, bigints (123L), smallints (123S), tinyints (123Y), bigdecimals (123BD), exponents`table_name` (Doris-style, preferred over double quotes)-- single line, /* */ multi-line, but /*+ hint */ preserved as HINT token)MATCH_ALL, MATCH_ANY, MATCH_PHRASE, MATCH_PHRASE_PREFIX, MATCH_PHRASE_EDGE, MATCH_REGEXP, MATCH_NAME, MATCH_NAME_GLOBRun the parser to generate AST and detect syntax errors.
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_parser.py "<sql_text>"
The parser supports major Doris statement types (based on DorisParser.g4):
Doris-specific syntax:
DISTRIBUTED BY {HASH(cols) | RANDOM} (BUCKETS n | AUTO)?PARTITION BY (RANGE | LIST)? ... (AUTO)? (auto partition, step partition, less-than, fixed, in-list)(DUPLICATE | AGGREGATE | UNIQUE) KEY (cols) (CLUSTER BY cols)?ENGINE = olap | mysql | elasticsearch | hive | hudi | iceberg | jdbc | ...PROPERTIES ('key'='value', ...)INSERT OVERWRITE TABLE ...LOAD LABEL ... (DATA INFILE (...) INTO TABLE ...)CREATE ROUTINE LOAD ... FROM type (...)EXPORT TABLE ... TO ...BACKUP SNAPSHOT ... TO repo (ON|EXCLUDE (...))?RESTORE SNAPSHOT ... FROM repo (ON|EXCLUDE (...))?EXPLAIN {PARSED|ANALYZED|REWRITTEN|LOGICAL|OPTIMIZED|PHYSICAL|SHAPE|MEMO|DISTRIBUTED|ALL} [VERBOSE|TREE|GRAPH|PLAN] [PROCESS]CREATE MATERIALIZED VIEW ... (DUPLICATE KEY ...)? PARTITION BY ... DISTRIBUTED BY ... AS query
BUILD [IMMEDIATE|DEFERRED], REFRESH [COMPLETE|AUTO], ON [MANUAL|SCHEDULE|COMMIT]TABLESAMPLE (...) (REPEATABLE n)?WITH cte_name AS (...) (CTE; Doris does not require explicit RECURSIVE keyword)OVER (PARTITION BY ... ORDER BY ... ROWS/RANGE ...)OUTFILE 'path' (FORMAT AS ...)? (PROPERTIES (...))?/*+ hint_name(...) */ and [hint_name] relation hintsALTER COLOCATE GROUP name SET (...)col MATCH_ALL '...', MATCH_PHRASE, MATCH_PHRASE_PREFIX, MATCH_PHRASE_EDGE, MATCH_ANY, MATCH_REGEXPHLL_UNION, BITMAP_UNION, QUANTILE_UNION, REPLACE_IF_NOT_NULLBased on tokenization and parsing results, execute syntax check rules.
Syntax Check Rules (34 rules):
| Rule ID | Name | Level | Description |
|---|---|---|---|
| SYN-ERR | Lexical Error | ERROR | Unrecognized characters in SQL text |
| SYN001 | Invalid Keyword | ERROR | Keyword not supported by Doris (not in 504-keyword list) |
| SYN002 | Reserved Keyword as Identifier | ERROR | Reserved keyword used as identifier without backticks |
| SYN003 | Syntax Structure Error | ERROR | Missing required clause or keyword |
| SYN004 | Clause Ordering Error | ERROR | SQL clause order does not conform to grammar |
| SYN005 | DISTRIBUTED BY Syntax Error | ERROR | Invalid distribution strategy (only HASH/RANDOM supported) |
| SYN006 | PARTITION BY Syntax Error | ERROR | Invalid partition definition (RANGE/LIST/AUTO) |
| SYN007 | BUCKETS Syntax Error | ERROR | Invalid BUCKETS clause (must be INTEGER or AUTO) |
| SYN008 | EXPLAIN planType Syntax Error | ERROR | Invalid EXPLAIN plan type (PARSED/ANALYZED/REWRITTEN/LOGICAL/OPTIMIZED/PHYSICAL/SHAPE/MEMO/DISTRIBUTED/ALL) |
| SYN009 | KEY Model Syntax Error | ERROR | Invalid data model (DUPLICATE/AGGREGATE/UNIQUE KEY) |
| SYN010 | PROPERTIES Syntax Error | ERROR | Invalid PROPERTIES clause structure |
| SYN011 | ENGINE Syntax Error | ERROR | Invalid ENGINE clause |
| SYN012 | INSERT OVERWRITE Syntax Error | ERROR | Invalid INSERT OVERWRITE TABLE structure |
| SYN013 | LOAD Syntax Error | ERROR | Invalid LOAD LABEL / BROKER LOAD structure |
| SYN014 | ROUTINE LOAD Syntax Error | ERROR | Invalid CREATE ROUTINE LOAD structure |
| SYN015 | EXPORT Syntax Error | ERROR | Invalid EXPORT TABLE ... TO structure |
| SYN016 | BACKUP/RESTORE SNAPSHOT Syntax Error | ERROR | Invalid BACKUP/RESTORE SNAPSHOT structure |
| SYN017 | CREATE MTMV Syntax Error | ERROR | Invalid CREATE MATERIALIZED VIEW structure |
| SYN018 | CREATE CATALOG Syntax Error | ERROR | Invalid CREATE CATALOG structure |
| SYN019 | CREATE USER/ROLE Syntax Error | ERROR | Invalid CREATE USER/ROLE structure |
| SYN020 | CREATE ROW POLICY Syntax Error | ERROR | Invalid CREATE ROW POLICY structure |
| SYN021 | CREATE SQL_BLOCK_RULE Syntax Error | ERROR | Invalid CREATE SQL_BLOCK_RULE structure |
| SYN022 | CREATE STAGE Syntax Error | ERROR | Invalid CREATE STAGE structure |
| SYN023 | CREATE JOB Syntax Error | ERROR | Invalid CREATE JOB ON SCHEDULE structure |
| SYN024 | CREATE ENCRYPTKEY Syntax Error | ERROR | Invalid CREATE ENCRYPTKEY structure |
| SYN025 | ADMIN SET/SHOW Syntax Error | ERROR | Invalid ADMIN statement structure |
| SYN026 | CANCEL Syntax Error | ERROR | Invalid CANCEL statement (LOAD/EXPORT/ALTER/BACKUP/RESTORE/WARM UP) |
| SYN027 | KILL Syntax Error | ERROR | Invalid KILL (CONNECTION/QUERY) statement |
| SYN028 | TABLESAMPLE Syntax Error | ERROR | Invalid TABLESAMPLE clause (PERCENT/ROWS, REPEATABLE) |
| SYN029 | OUTFILE Syntax Error | ERROR | Invalid OUTFILE clause (FORMAT AS, PROPERTIES) |
| SYN030 | Hint Syntax Error | WARNING | Invalid hint format (must be /*+ name(...) */ or [name]) |
| SYN031 | Full-text MATCH Syntax Error | ERROR | Invalid MATCH_ALL/MATCH_ANY/MATCH_PHRASE/MATCH_REGEXP usage |
| SYN032 | COLOCATE GROUP Syntax Error | ERROR | Invalid ALTER COLOCATE GROUP structure |
| SYN033 | GRANT/REVOKE Syntax Error | ERROR | Invalid GRANT/REVOKE privilege structure |
Based on AST and Token stream, execute specification check rules. Rules are derived from DorisParser.g4 grammar definitions and Apache Doris development best practices.
Specification Check Rules (46 rules):
| Rule ID | Name | Level | Category | Description |
|---|---|---|---|---|
| SPEC001 | Missing DISTRIBUTED BY | ERROR | Object Design | CREATE TABLE without distribution strategy (Doris requires DISTRIBUTED BY HASH or RANDOM) |
| SPEC002 | Missing ENGINE | INFO | Object Design | CREATE TABLE without explicit ENGINE (defaults to OLAP) |
| SPEC003 | SELECT * Prohibited | ERROR | Data Operation | Query must specify explicit column list |
| SPEC004 | DELETE/UPDATE without WHERE | ERROR | Data Operation | DML must include WHERE condition |
| SPEC005 | NOT IN Subquery | WARNING | Data Operation | Recommend NOT EXISTS or LEFT JOIN ... IS NULL |
| SPEC006 | DISTINCT Performance | INFO | Data Operation | DISTINCT may impact performance |
| SPEC007 | Implicit Type Conversion | WARNING | Data Operation | May cause index/zone-map invalidation |
| SPEC008 | LIKE Leading Wildcard | WARNING | Data Operation | Cannot use zone-map or index |
| SPEC009 | OR Condition | INFO | Data Operation | May impact execution plan |
| SPEC010 | IN List Too Long | WARNING | Data Operation | >1000 values recommend temp table |
| SPEC011 | FROM Subquery | INFO | Data Operation | Recommend CTE instead |
| SPEC012 | Cartesian Product | ERROR | Data Operation | Multi-table missing JOIN condition |
| SPEC013 | INSERT Missing Column List | WARNING | Data Operation | Relies on default column order |
| SPEC014 | Missing Table Comment | INFO | Object Design | Table without COMMENT |
| SPEC015 | Table Naming Convention | WARNING | Naming | Should use lowercase with underscores |
| SPEC016 | Column Naming Convention | WARNING | Naming | Should use lowercase with underscores |
| SPEC017 | Reserved Keyword as Identifier | ERROR | Naming | May cause syntax ambiguity |
| SPEC018 | Distribution Key Column Not Found | WARNING | Object Design | Distribution key should be actual table column |
| SPEC019 | Partition Key Same as Distribution Key | INFO | Object Design | May cause data skew |
| SPEC020 | Missing KEY Model Definition | INFO | Object Design | Recommend explicit DUPLICATE/AGGREGATE/UNIQUE KEY |
| SPEC021 | Large Table Should Have Partition | INFO | Object Design | Improve query and governance efficiency |
| SPEC022 | BUCKETS Count Recommendation | INFO | Object Design | Recommend appropriate bucket count for table size |
| SPEC023 | Column Should Have NOT NULL | INFO | Object Design | Optimizer can leverage NOT NULL |
| SPEC024 | DROP Should Use IF EXISTS | WARNING | SQL Dev | Prevent error when object not found |
| SPEC025 | INSERT Multi-VALUES | WARNING | SQL Dev | Multiple VALUES groups inefficient; use STREAM LOAD / BROKER LOAD |
| SPEC026 | Column-store Real-time INSERT | WARNING | SQL Dev | Frequent small-batch INSERT into Doris (columnar) causes compaction pressure |
| SPEC027 | Frequent UPDATE/DELETE | WARNING | SQL Dev | Doris UPDATE/DELETE is costly (read-merge-write) |
| SPEC028 | Function on Filter Column | WARNING | SQL Dev | Affects statistics accuracy and zone-map usage |
| SPEC029 | Large Table COUNT | WARNING | SQL Dev | Full table scan I/O cost |
| SPEC030 | Query Should Use LIMIT | INFO | SQL Dev | Avoid oversized result sets |
| SPEC031 | CTE Recursion Safety | WARNING | SQL Dev | Ensure termination condition for recursive CTE |
| SPEC032 | Use Catalog/DB Prefix | INFO | SQL Dev | Avoid ambiguity in multi-catalog scenarios |
| SPEC033 | View Nesting Depth ≤ 3 | INFO | Object Design | Requires cluster: query view dependencies |
| SPEC034 | Index Count > 5 | WARNING | Object Design | Requires cluster: query table indexes |
| SPEC035 | Non-pushdown SQL Prohibited | ERROR | SQL Dev | Requires cluster: EXPLAIN analysis |
| SPEC036 | BITMAP/HLL Column Needs Aggregation Type | WARNING | Object Design | BITMAP/HLL columns should specify BITMAP_UNION/HLL_UNION |
| SPEC037 | Use MTMV for Repeated Complex Queries | INFO | Object Design | Recommend MTMV for repeated aggregation queries |
| SPEC038 | Avoid Frequent OUTFILE Export | INFO | SQL Dev | Use EXPORT or broker for large exports |
| SPEC039 | VARCHAR Length Should Be Explicit | WARNING | Object Design | Avoid VARCHAR without length for large strings |
| SPEC040 | DECIMAL Precision Should Be Explicit | WARNING | Object Design | Use DECIMAL(p,s) or DECIMALV3(p,s), avoid bare DECIMAL |
| SPEC041 | COUNT(DISTINCT) Excessive Use | ERROR | Complex Query Limit | COUNT(DISTINCT) count > 5, may cause severe performance degradation |
| SPEC042 | NOT IN Subquery Prohibited | ERROR | Complex Query Limit | NOT IN subquery causes full scan and severe performance drop; use NOT EXISTS or LEFT JOIN |
| SPEC043 | Excessive JOINs | ERROR | Complex Query Limit | JOIN count > 20, may cause unstable query plans and high memory usage |
| SPEC044 | Excessive UNION ALLs | ERROR | Complex Query Limit | UNION ALL count > 20, may cause complex plans and high resource consumption |
| SPEC045 | Deeply Nested Subqueries | ERROR | Complex Query Limit | Subquery nesting depth > 20, may cause severe parse and execution performance issues |
| SPEC046 | SQL Statement Too Long | ERROR | Complex Query Limit | SQL text length > 2MB, may cause parse timeout or excessive memory usage |
Use the check engine to generate a Markdown format report:
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_checker.py "<sql_text>" all
Report format:
# Doris SQL Check Report
**Check Time**: 2026-07-17T10:00:00
**Statement Type**: SELECT
**Check Mode**: all
## Summary
| Metric | Value |
|--------|-------|
| Total Rules | 74 |
| Passed | 71 |
| Violations | 3 |
| Errors (ERROR) | 1 |
| Warnings (WARNING) | 1 |
| Infos (INFO) | 1 |
## Syntax Check
### [X] SYN003: Syntax Structure Error
- **Level**: ERROR
- **Position**: Line 1, Column 15
- **Description**: Missing FROM clause
- **Fix Suggestion**: Add FROM table_name
## Specification Check
### [!] SPEC003: SELECT * Prohibited
- **Level**: WARNING
- **Position**: Line 1, Column 8
- **Description**: Query uses SELECT *, should specify explicit column list
- **Fix Suggestion**: Replace SELECT * with specific column list
doris_sql_checker.py doris_sql_parser.py doris_sql_tokenizer.py
| Parameter | Required/Optional | Description | Default |
|---|---|---|---|
sql_text | Required | SQL statement to check | N/A |
check_mode | Optional | Check mode: syntax/spec/all | syntax+spec |
The check report is output in Markdown format, containing:
Each violation entry includes: rule ID, rule name, level, position (line/column), description, code snippet, and fix suggestion.
For simple SQL checks, run directly:
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_checker.py "<sql_text>" [syntax|spec|all]
Output is in JSON format. For Markdown format report, call in Python:
from doris_sql_checker import check_sql_markdown
report = check_sql_markdown("SELECT * FROM t1", "all")
print(report)
DISTRIBUTED BY HASH(分布键) or DISTRIBUTED BY RANDOM to avoid SPEC001DUPLICATE KEY/AGGREGATE KEY/UNIQUE KEY)all mode for comprehensive checkingrequires_mcp: true or "Requires cluster" (SPEC033, SPEC034, SPEC035) need cluster connection and are skipped in static modeMERGE INTO ... WHEN MATCHED or ON DUPLICATE KEY UPDATE — these will be flagged as syntax errors`), not double quotes — using double quotes for identifiers will trigger a warning| Document | Description |
|---|---|
| AST Schema | AST node type definitions for Doris SQL |
| Syntax Rules | 34 syntax check rule definitions |
| Specification Rules | 40 specification check rule definitions |
| Performance Rules | 11 performance check rule definitions (requires cluster) |
| Keywords | 504 Doris SQL keyword definitions (from DorisLexer.g4) |
| Grammar Rules | 100+ Doris statement type grammar definitions (from DorisParser.g4) |
information_schema.tables, backends, etc.)DorisParser.g4 (Nereids ANTLR4 grammar) from Doris 3.1.4 source