huawei-cloud-doris-sql-check · git:20260730.b4f666c · 2026-07-30 · sha256 9c76c6105383f434

huawei-cloud-doris-sql-check git:20260730.b4f666cA

Immutable. This exact content is served forever at /api/v1/blob/9c76c6105383f434.

---
name: huawei-cloud-doris-sql-check
description: |
  Comprehensive 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"
tags: [apache-doris, doris, sql, check, lint, nereids]
---

# Doris SQL Check Skill

You 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`).

## Overview

**Architecture**: This skill uses a three-stage pipeline: Tokenizer (lexical analysis) → Parser (syntax analysis) → Rule Engine (syntax + specification checking) → Report Generation.

**Applicable Scenarios**:

- Validate SQL syntax before executing on a Doris cluster (FE/BE)
- Review SQL statements against Apache Doris development best practices
- Check Doris-specific syntax (DISTRIBUTED BY HASH/RANDOM, PARTITION BY RANGE/LIST/AUTO, BUCKETS, PROPERTIES, ENGINE, DUPLICATE/AGGREGATE/UNIQUE KEY, INSERT OVERWRITE TABLE, LOAD LABEL, ROUTINE LOAD, EXPORT, MTMV, BACKUP/RESTORE SNAPSHOT, ADMIN SET/SHOW, CANCEL, KILL, TABLESAMPLE, OUTFILE, Hint /*+ */, full-text MATCH_*, COLOCATE GROUP)
- Identify potential performance anti-patterns in Doris SQL statements

**Typical Use Cases**:

- "Check this Doris SQL: SELECT * FROM t1"
- "Does this CREATE TABLE follow Doris specification (DISTRIBUTED BY, KEY model, PARTITION)?"
- "Validate the syntax of this INSERT OVERWRITE TABLE statement"
- "Review my Doris SQL for specification compliance"
- "Check if my SQL uses Doris-specific syntax correctly (MTMV, LOAD, EXPORT)"
- "Validate BACKUP/RESTORE SNAPSHOT syntax"
- "Check my ROUTINE LOAD job definition"

## Check Modes

| 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).

## Prerequisites

### 1. Python Requirements

- Python >= 3.8
- No additional packages required (standard library only)

### 2. Security Rules

- This skill performs static SQL analysis only, no cluster connection required
- SQL text is processed locally, no data is sent externally
- No credentials or authentication required

## Workflow

### Step 1: Receive Input

Receive the SQL statement and check mode from the user. If no mode is specified, default to syntax + spec.

### Step 2: Tokenization

Run the tokenizer to convert SQL text into a Token stream.

```bash
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_tokenizer.py "<sql_text>"
```

The tokenizer supports:

- All 504 Doris keywords (from `DorisLexer.g4` between `--DORIS-KEYWORD-LIST-START` and `--DORIS-KEYWORD-LIST-END`)
- Doris-specific tokens: `HINT` (`/*+ ... */`), `BACKQUOTED` (`` `ident` ``), `ARROW` (`->`), `NSEQ` (`<=>` null-safe eq), `EQ` (`=` or `==`), `NEQ` (`<>` or `!=`), `LTE` (`<=` or `!>`), `GTE` (`>=` or `!<`), `DOUBLEPIPES` (`||`), `LOGICALAND` (`&&`), `LOGICALNOT` (`!`)
- Literals: strings (`'...'` / `"..."`), integers, decimals, bigints (`123L`), smallints (`123S`), tinyints (`123Y`), bigdecimals (`123BD`), exponents
- Backquoted identifiers: `` `table_name` `` (Doris-style, preferred over double quotes)
- Comment skipping (`--` single line, `/* */` multi-line, but `/*+ hint */` preserved as HINT token)
- Full-text search operators: `MATCH_ALL`, `MATCH_ANY`, `MATCH_PHRASE`, `MATCH_PHRASE_PREFIX`, `MATCH_PHRASE_EDGE`, `MATCH_REGEXP`, `MATCH_NAME`, `MATCH_NAME_GLOB`

### Step 3: Parsing

Run the parser to generate AST and detect syntax errors.

```bash
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`):

- **DML**: SELECT (with CTE, set ops, window, TABLESAMPLE), INSERT INTO/OVERWRITE TABLE, UPDATE, DELETE, LOAD (BROKER LOAD), EXPORT, COPY INTO, TRUNCATE
- **DDL**: CREATE TABLE (with DISTRIBUTED BY, PARTITION BY, KEY model, ENGINE, PROPERTIES), CREATE TABLE LIKE, CREATE VIEW, CREATE MTMV (Multi-Table Materialized View), CREATE INDEX (BITMAP/NGRAM_BF/INVERTED), ALTER TABLE (ADD/MODIFY/DROP/RENAME COLUMN, ADD/DROP PARTITION, ADD/DROP INDEX, ROLLUP, TAG/BRANCH), DROP TABLE/VIEW/INDEX, CREATE CATALOG, CREATE DATABASE, CREATE USER/ROLE, CREATE RESOURCE, CREATE STAGE, CREATE ENCRYPTKEY, CREATE JOB, CREATE ROW POLICY, CREATE SQL_BLOCK_RULE, CREATE STORAGE VAULT/POLICY, CREATE WORKLOAD GROUP/POLICY
- **DCL**: GRANT/REVOKE (table/resource/role privileges)
- **TCL**: BEGIN/START TRANSACTION, COMMIT, ROLLBACK
- **Utility**: EXPLAIN (PARSED/ANALYZED/REWRITTEN/LOGICAL/OPTIMIZED/PHYSICAL/SHAPE/MEMO/DISTRIBUTED/ALL, VERBOSE/TREE/GRAPH/PLAN), SET (variables/options), SHOW (50+ variants), DESC/DESCRIBE, ADMIN SET/SHOW (replica, frontend config, tablet diagnose, trash, TDE), KILL (CONNECTION/QUERY), CANCEL (LOAD/EXPORT/ALTER TABLE/BACKUP/RESTORE/WARM UP), BACKUP/RESTORE SNAPSHOT, RECOVER (DATABASE/TABLE/PARTITION), CLEAN (LABEL/PROFILE/QUERY STATS), INSTALL/UNINSTALL PLUGIN, LOCK/UNLOCK TABLES, WARM UP, SYNC, HELP, CALL PROCEDURE

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)
- Window functions: `OVER (PARTITION BY ... ORDER BY ... ROWS/RANGE ...)`
- `OUTFILE 'path' (FORMAT AS ...)? (PROPERTIES (...))?`
- Hints: `/*+ hint_name(...) */` and `[hint_name]` relation hints
- `ALTER COLOCATE GROUP name SET (...)`
- Full-text search: `col MATCH_ALL '...'`, `MATCH_PHRASE`, `MATCH_PHRASE_PREFIX`, `MATCH_PHRASE_EDGE`, `MATCH_ANY`, `MATCH_REGEXP`
- Aggregate unions: `HLL_UNION`, `BITMAP_UNION`, `QUANTILE_UNION`, `REPLACE_IF_NOT_NULL`
- Doris data types: TINYINT, SMALLINT, INT, BIGINT, LARGEINT, BOOLEAN, FLOAT, DOUBLE, DATE, DATETIME, DATEV2, DATETIMEV2, DATEV1, DATETIMEV1, BITMAP, QUANTILE_STATE, HLL, AGG_STATE, STRING, JSON, JSONB, TEXT, VARCHAR, CHAR, DECIMAL, DECIMALV2, DECIMALV3, IPV4, IPV6, ARRAY, MAP, STRUCT, VARIANT

### Step 4: Syntax Check

Based 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                                                                    |

### Step 5: Specification Check

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                  |

### Step 6: Generate Report

Use the check engine to generate a Markdown format report:

```bash
python ~/.cac/skills/huawei-cloud-doris-sql-check/scripts/doris_sql_checker.py "<sql_text>" all
```

Report format:

```markdown
# 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
```

## Core Commands
[doris_sql_checker.py](scripts/doris_sql_checker.py)
[doris_sql_parser.py](scripts/doris_sql_parser.py)
[doris_sql_tokenizer.py](scripts/doris_sql_tokenizer.py)
     
## Parameters

| Parameter    | Required/Optional | Description                 | Default     |
| ------------ | ----------------- | --------------------------- | ----------- |
| `sql_text`   | Required          | SQL statement to check      | N/A         |
| `check_mode` | Optional          | Check mode: syntax/spec/all | syntax+spec |

## Output Format

The check report is output in Markdown format, containing:

- **Summary table**: Total rules, passed, violations by level
- **Syntax check section**: Violations from syntax rules (SYN-ERR, SYN001-SYN033)
- **Specification check section**: Violations from specification rules (SPEC001-SPEC040)
- **Original SQL**: The checked SQL statement

Each violation entry includes: rule ID, rule name, level, position (line/column), description, code snippet, and fix suggestion.

## Quick Check Command

For simple SQL checks, run directly:

```bash
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:

```python
from doris_sql_checker import check_sql_markdown
report = check_sql_markdown("SELECT * FROM t1", "all")
print(report)
```

## Best Practices

1. Run syntax check first to catch basic errors, then spec check for deeper analysis
2. For CREATE TABLE statements, always include `DISTRIBUTED BY HASH(分布键)` or `DISTRIBUTED BY RANDOM` to avoid SPEC001
3. For Doris tables, explicitly specify the KEY model (`DUPLICATE KEY`/`AGGREGATE KEY`/`UNIQUE KEY`)
4. Use `all` mode for comprehensive checking
5. Rules marked with `requires_mcp: true` or "Requires cluster" (SPEC033, SPEC034, SPEC035) need cluster connection and are skipped in static mode
6. Doris does NOT support `MERGE INTO ... WHEN MATCHED` or `ON DUPLICATE KEY UPDATE` — these will be flagged as syntax errors
7. Doris identifiers use backticks (`` ` ``), not double quotes — using double quotes for identifiers will trigger a warning
8. For large data loading, prefer STREAM LOAD / BROKER LOAD / ROUTINE LOAD over multi-row INSERT VALUES (SPEC025)

## References

| Document                                     | Description                                                         |
| -------------------------------------------- | ------------------------------------------------------------------- |
| [AST Schema](references/ast_schema.md)       | AST node type definitions for Doris SQL                             |
| [Syntax Rules](rules/syntax_rules.yaml)      | 34 syntax check rule definitions                                    |
| [Specification Rules](rules/spec_rules.yaml) | 40 specification check rule definitions                             |
| [Performance Rules](rules/perf_rules.yaml)   | 11 performance check rule definitions (requires cluster)            |
| [Keywords](rules/keywords.py)                | 504 Doris SQL keyword definitions (from DorisLexer.g4)              |
| [Grammar Rules](rules/grammar_rules.py)      | 100+ Doris statement type grammar definitions (from DorisParser.g4) |

## Notes

1. **Syntax and specification checks** do not require cluster connection, can run offline
2. **Rules marked "Requires cluster"** (SPEC033, SPEC034, SPEC035) are skipped in static mode
3. **Performance rules** (PERF001-PERF011) are defined in rules/perf_rules.yaml but require cluster connection for execution (EXPLAIN ANALYZE, system tables like `information_schema.tables`, `backends`, etc.)
4. Doris-specific syntax checking (DISTRIBUTED BY, PARTITION BY, BUCKETS, PROPERTIES, ENGINE, DUPLICATE/AGGREGATE/UNIQUE KEY, INSERT OVERWRITE, LOAD, EXPORT, MTMV, BACKUP/RESTORE, ADMIN, CANCEL, KILL, TABLESAMPLE, OUTFILE, Hint, MATCH, COLOCATE GROUP) is based on `DorisParser.g4` (Nereids ANTLR4 grammar) from Doris 3.1.4 source
5. The check engine includes a custom tokenizer and recursive descent parser, no external SQL parsing libraries required (no ANTLR runtime needed)
6. **Version compatibility**: This skill is based on Doris 3.1.4 grammar. Doris 2.1.x / 3.0.x / 3.1.x / 4.x share the same Nereids grammar for most constructs; minor differences may exist for newer syntax (e.g., 4.x added features). Verify against your cluster's version before relying on specific rules.