Skip to content

Commit c9e8bb4

Browse files
authored
Parse compression codecs with no parameters (#197)
Compression codecs such as `DoubleDelta` do not require any additional positional parameters and infer defaults, such as `CODEC(DoubleDelta)`. This commit doesn't continue parsing a codec if there's no comma indicating additional parameters to the codec.
1 parent 06f1e25 commit c9e8bb4

File tree

5 files changed

+135
-22
lines changed

5 files changed

+135
-22
lines changed

parser/ast.go

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4823,11 +4823,13 @@ func (c *CompressionCodec) String() string {
48234823
builder.WriteByte(',')
48244824
builder.WriteByte(' ')
48254825
}
4826-
builder.WriteString(c.Name.String())
4827-
if c.Level != nil {
4828-
builder.WriteByte('(')
4829-
builder.WriteString(c.Level.String())
4830-
builder.WriteByte(')')
4826+
if c.Name != nil {
4827+
builder.WriteString(c.Name.String())
4828+
if c.Level != nil {
4829+
builder.WriteByte('(')
4830+
builder.WriteString(c.Level.String())
4831+
builder.WriteByte(')')
4832+
}
48314833
}
48324834
builder.WriteByte(')')
48334835
return builder.String()
@@ -4836,16 +4838,20 @@ func (c *CompressionCodec) String() string {
48364838
func (c *CompressionCodec) Accept(visitor ASTVisitor) error {
48374839
visitor.Enter(c)
48384840
defer visitor.Leave(c)
4839-
if err := c.Type.Accept(visitor); err != nil {
4840-
return err
4841+
if c.Type != nil {
4842+
if err := c.Type.Accept(visitor); err != nil {
4843+
return err
4844+
}
48414845
}
48424846
if c.TypeLevel != nil {
48434847
if err := c.TypeLevel.Accept(visitor); err != nil {
48444848
return err
48454849
}
48464850
}
4847-
if err := c.Name.Accept(visitor); err != nil {
4848-
return err
4851+
if c.Name != nil {
4852+
if err := c.Name.Accept(visitor); err != nil {
4853+
return err
4854+
}
48494855
}
48504856
if c.Level != nil {
48514857
if err := c.Level.Accept(visitor); err != nil {

parser/parser_column.go

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,39 +1166,48 @@ func (p *Parser) tryParseCompressionCodecs(pos Pos) (*CompressionCodec, error) {
11661166
}
11671167

11681168
// parse codec name
1169-
name, err := p.parseIdent()
1169+
codecType, err := p.parseIdent()
11701170
if err != nil {
11711171
return nil, err
11721172
}
11731173
// parse DELTA if CODEC(Delta, ZSTD(1))
11741174
// or CODEC(Delta(9), ZSTD(1)) or CODEC(T64, ZSTD(1))
1175-
var codecType *Ident
1175+
var name *Ident
11761176
var typeLevel *NumberLiteral
1177-
switch strings.ToUpper(name.Name) {
1177+
switch strings.ToUpper(codecType.Name) {
11781178
case "DELTA", "DOUBLEDELTA", "T64", "GORILLA":
1179-
codecType = name
11801179
// try parse delta level
11811180
typeLevel, err = p.tryParseCompressionLevel(p.Pos())
11821181
if err != nil {
11831182
return nil, err
11841183
}
1185-
// consume comma
1186-
if err := p.expectTokenKind(TokenKindComma); err != nil {
1187-
return nil, err
1184+
1185+
if p.matchTokenKind(TokenKindComma) {
1186+
if err := p.expectTokenKind(TokenKindComma); err != nil {
1187+
return nil, err
1188+
}
1189+
name, err = p.parseIdent()
1190+
if err != nil {
1191+
return nil, err
1192+
}
11881193
}
1189-
name, err = p.parseIdent()
1194+
case "ZSTD", "LZ4HC", "LH4":
1195+
// For compression codecs, try to parse level
1196+
typeLevel, err = p.tryParseCompressionLevel(p.Pos())
11901197
if err != nil {
11911198
return nil, err
11921199
}
11931200
}
11941201

11951202
var level *NumberLiteral
11961203
// TODO: check if the codec name is valid
1197-
switch strings.ToUpper(name.Name) {
1198-
case "ZSTD", "LZ4HC", "LH4":
1199-
level, err = p.tryParseCompressionLevel(p.Pos())
1200-
if err != nil {
1201-
return nil, err
1204+
if name != nil {
1205+
switch strings.ToUpper(name.Name) {
1206+
case "ZSTD", "LZ4HC", "LH4":
1207+
level, err = p.tryParseCompressionLevel(p.Pos())
1208+
if err != nil {
1209+
return nil, err
1210+
}
12021211
}
12031212
}
12041213

@@ -1207,6 +1216,21 @@ func (p *Parser) tryParseCompressionCodecs(pos Pos) (*CompressionCodec, error) {
12071216
return nil, err
12081217
}
12091218

1219+
// If there's only one codec (no second name), store it in Name field instead of Type
1220+
// This handles cases like CODEC(DoubleDelta) or CODEC(ZSTD(1))
1221+
if name == nil {
1222+
return &CompressionCodec{
1223+
CodecPos: pos,
1224+
RightParenPos: rightParenPos,
1225+
Type: nil,
1226+
TypeLevel: nil,
1227+
Name: codecType,
1228+
Level: typeLevel,
1229+
}, nil
1230+
}
1231+
1232+
// Two codecs: Type is the preprocessing codec, Name is the compression codec
1233+
// e.g., CODEC(DoubleDelta, ZSTD(1))
12101234
return &CompressionCodec{
12111235
CodecPos: pos,
12121236
RightParenPos: rightParenPos,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CREATE TABLE shark_attacks (
2+
timestamp DateTime CODEC(DoubleDelta),
3+
);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-- Origin SQL:
2+
CREATE TABLE shark_attacks (
3+
timestamp DateTime CODEC(DoubleDelta),
4+
);
5+
6+
-- Format SQL:
7+
CREATE TABLE shark_attacks (timestamp DateTime CODEC(DoubleDelta));
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
[
2+
{
3+
"CreatePos": 0,
4+
"StatementEnd": 0,
5+
"OrReplace": false,
6+
"Name": {
7+
"Database": null,
8+
"Table": {
9+
"Name": "shark_attacks",
10+
"QuoteType": 1,
11+
"NamePos": 13,
12+
"NameEnd": 26
13+
}
14+
},
15+
"IfNotExists": false,
16+
"UUID": null,
17+
"OnCluster": null,
18+
"TableSchema": {
19+
"SchemaPos": 27,
20+
"SchemaEnd": 72,
21+
"Columns": [
22+
{
23+
"NamePos": 33,
24+
"ColumnEnd": 70,
25+
"Name": {
26+
"Ident": {
27+
"Name": "timestamp",
28+
"QuoteType": 1,
29+
"NamePos": 33,
30+
"NameEnd": 42
31+
},
32+
"DotIdent": null
33+
},
34+
"Type": {
35+
"Name": {
36+
"Name": "DateTime",
37+
"QuoteType": 1,
38+
"NamePos": 43,
39+
"NameEnd": 51
40+
}
41+
},
42+
"NotNull": null,
43+
"Nullable": null,
44+
"DefaultExpr": null,
45+
"MaterializedExpr": null,
46+
"AliasExpr": null,
47+
"Codec": {
48+
"CodecPos": 52,
49+
"RightParenPos": 70,
50+
"Type": null,
51+
"TypeLevel": null,
52+
"Name": {
53+
"Name": "DoubleDelta",
54+
"QuoteType": 1,
55+
"NamePos": 58,
56+
"NameEnd": 69
57+
},
58+
"Level": null
59+
},
60+
"TTL": null,
61+
"Comment": null,
62+
"CompressionCodec": null
63+
}
64+
],
65+
"AliasTable": null,
66+
"TableFunction": null
67+
},
68+
"Engine": null,
69+
"SubQuery": null,
70+
"HasTemporary": false,
71+
"Comment": null
72+
}
73+
]

0 commit comments

Comments
 (0)