Skip to content

Commit cfc05a6

Browse files
committed
Add support for PRIMARY KEY in column definition list
Added parsing for PRIMARY KEY specified inline within the column definition list (e.g., `CREATE TABLE t (n int, PRIMARY KEY n)`). This is stored in a new ColumnsPrimaryKey field, separate from the table-level PrimaryKey. The explain output now correctly renders inline PRIMARY KEY columns as Identifier nodes directly under Columns definition. This fixes 16+ statements across multiple tests including: - 01166_truncate_multiple_partitions - 01516_create_table_primary_key - 01532_primary_key_without_order_by_zookeeper - 02400_create_table_on_cluster_normalization - And various other tests
1 parent 6623f83 commit cfc05a6

File tree

19 files changed

+56
-66
lines changed

19 files changed

+56
-66
lines changed

ast/ast.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,11 +272,12 @@ type CreateQuery struct {
272272
Columns []*ColumnDeclaration `json:"columns,omitempty"`
273273
Indexes []*IndexDefinition `json:"indexes,omitempty"`
274274
Projections []*Projection `json:"projections,omitempty"`
275-
Constraints []*Constraint `json:"constraints,omitempty"`
276-
Engine *EngineClause `json:"engine,omitempty"`
277-
OrderBy []Expression `json:"order_by,omitempty"`
278-
PartitionBy Expression `json:"partition_by,omitempty"`
279-
PrimaryKey []Expression `json:"primary_key,omitempty"`
275+
Constraints []*Constraint `json:"constraints,omitempty"`
276+
ColumnsPrimaryKey []Expression `json:"columns_primary_key,omitempty"` // PRIMARY KEY in column list
277+
Engine *EngineClause `json:"engine,omitempty"`
278+
OrderBy []Expression `json:"order_by,omitempty"`
279+
PartitionBy Expression `json:"partition_by,omitempty"`
280+
PrimaryKey []Expression `json:"primary_key,omitempty"`
280281
SampleBy Expression `json:"sample_by,omitempty"`
281282
TTL *TTLClause `json:"ttl,omitempty"`
282283
Settings []*SettingExpr `json:"settings,omitempty"`

internal/explain/statements.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string,
219219
if len(primaryKeyColumns) > 0 {
220220
childrenCount++ // Add for Function tuple containing PRIMARY KEY columns
221221
}
222+
// Check for inline PRIMARY KEY (from column list, e.g., "n int, primary key n")
223+
if len(n.ColumnsPrimaryKey) > 0 {
224+
childrenCount++ // Add for the primary key identifier(s)
225+
}
222226
fmt.Fprintf(sb, "%s Columns definition (children %d)\n", indent, childrenCount)
223227
if len(n.Columns) > 0 {
224228
fmt.Fprintf(sb, "%s ExpressionList (children %d)\n", indent, len(n.Columns))
@@ -254,6 +258,12 @@ func explainCreateQuery(sb *strings.Builder, n *ast.CreateQuery, indent string,
254258
fmt.Fprintf(sb, "%s Identifier %s\n", indent, colName)
255259
}
256260
}
261+
// Output inline PRIMARY KEY (from column list)
262+
if len(n.ColumnsPrimaryKey) > 0 {
263+
for _, pk := range n.ColumnsPrimaryKey {
264+
Node(sb, pk, depth+2)
265+
}
266+
}
257267
}
258268
// For materialized views, output AsSelect before storage definition
259269
if n.Materialized && n.AsSelect != nil {

parser/parser.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,6 +1977,34 @@ func (p *Parser) parseCreateTable(create *ast.CreateQuery) {
19771977
p.nextToken()
19781978
}
19791979
}
1980+
} else if p.currentIs(token.PRIMARY) {
1981+
// Handle PRIMARY KEY as table constraint: PRIMARY KEY (col1, col2) or PRIMARY KEY col
1982+
p.nextToken() // skip PRIMARY
1983+
if p.currentIs(token.KEY) {
1984+
p.nextToken() // skip KEY
1985+
}
1986+
// Parse the primary key column(s) into create.PrimaryKey
1987+
if p.currentIs(token.LPAREN) {
1988+
p.nextToken() // skip (
1989+
for !p.currentIs(token.RPAREN) && !p.currentIs(token.EOF) {
1990+
expr := p.parseExpression(LOWEST)
1991+
if expr != nil {
1992+
create.ColumnsPrimaryKey = append(create.ColumnsPrimaryKey, expr)
1993+
}
1994+
if p.currentIs(token.COMMA) {
1995+
p.nextToken()
1996+
} else {
1997+
break
1998+
}
1999+
}
2000+
p.expect(token.RPAREN)
2001+
} else {
2002+
// Single column: PRIMARY KEY col
2003+
expr := p.parseExpression(LOWEST)
2004+
if expr != nil {
2005+
create.ColumnsPrimaryKey = append(create.ColumnsPrimaryKey, expr)
2006+
}
2007+
}
19802008
} else {
19812009
col := p.parseColumnDeclaration()
19822010
if col != nil {
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"explain_todo": {
33
"stmt16": true,
4-
"stmt23": true,
54
"stmt9": true
65
}
76
}

parser/testdata/01166_truncate_multiple_partitions/metadata.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
"explain_todo": {
33
"stmt10": true,
44
"stmt11": true,
5-
"stmt17": true,
65
"stmt22": true,
76
"stmt23": true,
87
"stmt24": true,
98
"stmt25": true,
10-
"stmt3": true,
119
"stmt8": true,
1210
"stmt9": true
1311
}

parser/testdata/01516_create_table_primary_key/metadata.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"stmt22": true,
77
"stmt28": true,
88
"stmt31": true,
9-
"stmt32": true,
10-
"stmt7": true
9+
"stmt32": true
1110
}
1211
}
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"explain_todo": {
3-
"stmt13": true,
43
"stmt22": true,
5-
"stmt29": true,
64
"stmt38": true
75
}
86
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"explain_todo":{"stmt2":true}}
1+
{}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
{
22
"explain_todo": {
3-
"stmt2": true,
43
"stmt6": true
54
}
65
}
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1 @@
1-
{
2-
"explain_todo": {
3-
"stmt1": true
4-
}
5-
}
1+
{}

0 commit comments

Comments
 (0)