Skip to content

Commit 338261b

Browse files
Ajit Pratap SinghAjit Pratap Singh
authored andcommitted
feat(parser): ClickHouse CODEC(...) column option (#482)
1 parent 144e3ca commit 338261b

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2026 GoSQLX Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
5+
package parser_test
6+
7+
import (
8+
"testing"
9+
10+
"github.com/ajitpratap0/GoSQLX/pkg/gosqlx"
11+
"github.com/ajitpratap0/GoSQLX/pkg/sql/keywords"
12+
)
13+
14+
// TestClickHouseCODEC verifies the ClickHouse CODEC(...) column option
15+
// parses in CREATE TABLE. Regression for #482.
16+
func TestClickHouseCODEC(t *testing.T) {
17+
queries := map[string]string{
18+
"single_codec": `CREATE TABLE t (
19+
id UInt64,
20+
payload String CODEC(ZSTD(3))
21+
) ENGINE = MergeTree() ORDER BY id`,
22+
23+
"chained_codec": `CREATE TABLE t (
24+
id UInt64,
25+
ts DateTime CODEC(Delta, LZ4)
26+
) ENGINE = MergeTree() ORDER BY id`,
27+
28+
"delta_with_width": `CREATE TABLE t (
29+
id UInt64 CODEC(Delta(8), ZSTD)
30+
) ENGINE = MergeTree() ORDER BY id`,
31+
}
32+
for name, q := range queries {
33+
q := q
34+
t.Run(name, func(t *testing.T) {
35+
if _, err := gosqlx.ParseWithDialect(q, keywords.DialectClickHouse); err != nil {
36+
t.Fatalf("parse failed: %v", err)
37+
}
38+
})
39+
}
40+
}

pkg/sql/parser/ddl_columns.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
goerrors "github.com/ajitpratap0/GoSQLX/pkg/errors"
2424
"github.com/ajitpratap0/GoSQLX/pkg/models"
2525
"github.com/ajitpratap0/GoSQLX/pkg/sql/ast"
26+
"github.com/ajitpratap0/GoSQLX/pkg/sql/keywords"
2627
)
2728

2829
// parseColumnName parses a column name in DDL context, accepting reserved keywords
@@ -92,6 +93,27 @@ func (p *Parser) parseColumnDef() (*ast.ColumnDef, error) {
9293
Type: dataTypeStr,
9394
}
9495

96+
// ClickHouse column options that may appear between the type and the
97+
// standard constraint list: CODEC(...), DEFAULT expr, MATERIALIZED expr,
98+
// ALIAS expr, EPHEMERAL expr, TTL expr. Consume permissively; they are
99+
// appended to the type string for now so formatters can round-trip, and
100+
// not yet modeled on the AST.
101+
if p.dialect == string(keywords.DialectClickHouse) {
102+
for {
103+
upper := strings.ToUpper(p.currentToken.Token.Value)
104+
if upper == "CODEC" && p.peekToken().Token.Type == models.TokenTypeLParen {
105+
p.advance() // CODEC
106+
args, err := p.parseTypeArgsString()
107+
if err != nil {
108+
return nil, err
109+
}
110+
colDef.Type += " CODEC" + args
111+
continue
112+
}
113+
break
114+
}
115+
}
116+
95117
// Parse column constraints
96118
for {
97119
constraint, ok, err := p.parseColumnConstraint()

0 commit comments

Comments
 (0)