Skip to content

Commit 6c02832

Browse files
rebeliceclaude
andcommitted
fix(parser): translate 8 missing grammar rule assignments
Systematically audit and fix all grammar rules where positional references ($N) were parsed but never assigned to AST node fields: 1. GROUP BY DISTINCT: add GroupClause struct, fix set_quantifier to use int enum, propagate GroupDistinct to SelectStmt 2. CreateStmt: apply OptTemp via relpersistenceForTemp() in all 8 variants to set RangeVar.Relpersistence 3. ViewStmt: apply OptTemp in all 4 variants 4. relpersistenceForTemp(): handle UNLOGGED (tempFlag==2 → 'u') 5. makeRangeVar(): set default Relpersistence to 'p' 6. json_aggregate_func: extract JsonAggConstructor and assign Agg_filter and Over from filter_clause/over_clause 7. key_action: add KeyAction/KeyActions structs to carry column list through FK constraint rules, populate Constraint.FkDelsetcols 8. func_expr_windowless: add missing json_aggregate_func alternative Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5ee13b2 commit 6c02832

File tree

7 files changed

+23445
-23022
lines changed

7 files changed

+23445
-23022
lines changed

parser/gram.y

Lines changed: 125 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import (
2828
typename *nodes.TypeName // for Typename values
2929
partspec *nodes.PartitionSpec
3030
partbound *nodes.PartitionBoundSpec
31+
grpclause *GroupClause // for GROUP BY clause
32+
keyaction *KeyAction // for FK key_action
33+
keyactions *KeyActions // for FK key_actions
3134
}
3235

3336
// Token types from the lexer
@@ -132,7 +135,8 @@ import (
132135
%type <node> opt_repeatable_clause
133136
%type <ival> join_type
134137
%type <list> stmtmulti target_list from_list opt_target_list
135-
%type <list> group_clause group_by_list
138+
%type <grpclause> group_clause
139+
%type <list> group_by_list
136140
%type <node> group_by_item having_clause
137141
%type <node> empty_grouping_set cube_clause rollup_clause grouping_sets_clause
138142
%type <list> sort_clause opt_sort_clause sortby_list
@@ -147,7 +151,8 @@ import (
147151
%type <ival> opt_asc_desc
148152
%type <ival> Iconst
149153
%type <str> Sconst
150-
%type <boolean> opt_all_clause set_quantifier
154+
%type <boolean> opt_all_clause
155+
%type <ival> set_quantifier
151156
%type <list> distinct_clause opt_distinct_clause
152157
%type <node> with_clause opt_with_clause common_table_expr
153158
%type <ival> opt_materialized
@@ -373,7 +378,10 @@ import (
373378
%type <boolean> opt_instead opt_trusted
374379
%type <list> handler_name opt_inline_handler opt_validator
375380
%type <ival> ConstraintAttributeSpec ConstraintAttributeElem
376-
%type <ival> key_match key_actions key_update key_delete key_action
381+
%type <ival> key_match
382+
%type <keyaction> key_action
383+
%type <keyaction> key_update key_delete
384+
%type <keyactions> key_actions
377385
%type <list> opt_c_include ExclusionConstraintList
378386
%type <list> ExclusionConstraintElem
379387
%type <str> OptConsTableSpace ExistingIndex
@@ -1373,6 +1381,7 @@ CreateStmt:
13731381
CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')' OptInherit OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
13741382
{
13751383
rv := makeRangeVar($4)
1384+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
13761385
$$ = &nodes.CreateStmt{
13771386
Relation: rv.(*nodes.RangeVar),
13781387
TableElts: $6,
@@ -1387,6 +1396,7 @@ CreateStmt:
13871396
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name '(' OptTableElementList ')' OptInherit OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
13881397
{
13891398
rv := makeRangeVar($7)
1399+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
13901400
$$ = &nodes.CreateStmt{
13911401
Relation: rv.(*nodes.RangeVar),
13921402
TableElts: $9,
@@ -1402,6 +1412,7 @@ CreateStmt:
14021412
| CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name ForValues OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
14031413
{
14041414
rv := makeRangeVar($4)
1415+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14051416
inh := makeRangeVar($7)
14061417
$$ = &nodes.CreateStmt{
14071418
Relation: rv.(*nodes.RangeVar),
@@ -1417,6 +1428,7 @@ CreateStmt:
14171428
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name ForValues OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
14181429
{
14191430
rv := makeRangeVar($7)
1431+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14201432
inh := makeRangeVar($10)
14211433
$$ = &nodes.CreateStmt{
14221434
Relation: rv.(*nodes.RangeVar),
@@ -1433,6 +1445,7 @@ CreateStmt:
14331445
| CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name '(' TypedTableElementList ')' ForValues OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
14341446
{
14351447
rv := makeRangeVar($4)
1448+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14361449
inh := makeRangeVar($7)
14371450
$$ = &nodes.CreateStmt{
14381451
Relation: rv.(*nodes.RangeVar),
@@ -1449,6 +1462,7 @@ CreateStmt:
14491462
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF qualified_name '(' TypedTableElementList ')' ForValues OptPartitionSpec OptAccessMethod OptWith OnCommitOption OptTableSpace
14501463
{
14511464
rv := makeRangeVar($7)
1465+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14521466
inh := makeRangeVar($10)
14531467
$$ = &nodes.CreateStmt{
14541468
Relation: rv.(*nodes.RangeVar),
@@ -1467,6 +1481,7 @@ CreateStmt:
14671481
| CREATE OptTemp TABLE qualified_name OF any_name OptTypedTableElementList OptAccessMethod OptWith OnCommitOption OptTableSpace
14681482
{
14691483
rv := makeRangeVar($4)
1484+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14701485
tn := makeTypeNameFromNameList($6).(*nodes.TypeName)
14711486
$$ = &nodes.CreateStmt{
14721487
Relation: rv.(*nodes.RangeVar),
@@ -1481,6 +1496,7 @@ CreateStmt:
14811496
| CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name OF any_name OptTypedTableElementList OptAccessMethod OptWith OnCommitOption OptTableSpace
14821497
{
14831498
rv := makeRangeVar($7)
1499+
rv.(*nodes.RangeVar).Relpersistence = relpersistenceForTemp($2)
14841500
tn := makeTypeNameFromNameList($9).(*nodes.TypeName)
14851501
$$ = &nodes.CreateStmt{
14861502
Relation: rv.(*nodes.RangeVar),
@@ -1918,13 +1934,14 @@ ColConstraintElem:
19181934
{
19191935
rv := makeRangeVar($2)
19201936
n := &nodes.Constraint{
1921-
Contype: nodes.CONSTR_FOREIGN,
1922-
Pktable: rv.(*nodes.RangeVar),
1923-
PkAttrs: $3,
1924-
FkMatchtype: byte($4),
1925-
FkUpdaction: byte($5 >> 8),
1926-
FkDelaction: byte($5 & 0xFF),
1927-
Location: -1,
1937+
Contype: nodes.CONSTR_FOREIGN,
1938+
Pktable: rv.(*nodes.RangeVar),
1939+
PkAttrs: $3,
1940+
FkMatchtype: byte($4),
1941+
FkUpdaction: $5.UpdateAction.Action,
1942+
FkDelaction: $5.DeleteAction.Action,
1943+
FkDelsetcols: $5.DeleteAction.Cols,
1944+
Location: -1,
19281945
InitiallyValid: true,
19291946
}
19301947
applyConstraintAttrs(n, $6)
@@ -2085,14 +2102,15 @@ ConstraintElem:
20852102
{
20862103
rv := makeRangeVar($7)
20872104
n := &nodes.Constraint{
2088-
Contype: nodes.CONSTR_FOREIGN,
2089-
FkAttrs: $4,
2090-
Pktable: rv.(*nodes.RangeVar),
2091-
PkAttrs: $8,
2092-
FkMatchtype: byte($9),
2093-
FkUpdaction: byte($10 >> 8),
2094-
FkDelaction: byte($10 & 0xFF),
2095-
Location: -1,
2105+
Contype: nodes.CONSTR_FOREIGN,
2106+
FkAttrs: $4,
2107+
Pktable: rv.(*nodes.RangeVar),
2108+
PkAttrs: $8,
2109+
FkMatchtype: byte($9),
2110+
FkUpdaction: $10.UpdateAction.Action,
2111+
FkDelaction: $10.DeleteAction.Action,
2112+
FkDelsetcols: $10.DeleteAction.Cols,
2113+
Location: -1,
20962114
InitiallyValid: true,
20972115
}
20982116
applyConstraintAttrs(n, $11)
@@ -2144,11 +2162,16 @@ key_match:
21442162
* high byte = update action, low byte = delete action
21452163
*/
21462164
key_actions:
2147-
key_update { $$ = ($1 << 8) | int64('a') }
2148-
| key_delete { $$ = (int64('a') << 8) | $1 }
2149-
| key_update key_delete { $$ = ($1 << 8) | $2 }
2150-
| key_delete key_update { $$ = ($2 << 8) | $1 }
2151-
| /* EMPTY */ { $$ = (int64('a') << 8) | int64('a') }
2165+
key_update
2166+
{ $$ = &KeyActions{UpdateAction: $1, DeleteAction: &KeyAction{Action: 'a'}} }
2167+
| key_delete
2168+
{ $$ = &KeyActions{UpdateAction: &KeyAction{Action: 'a'}, DeleteAction: $1} }
2169+
| key_update key_delete
2170+
{ $$ = &KeyActions{UpdateAction: $1, DeleteAction: $2} }
2171+
| key_delete key_update
2172+
{ $$ = &KeyActions{UpdateAction: $2, DeleteAction: $1} }
2173+
| /* EMPTY */
2174+
{ $$ = &KeyActions{UpdateAction: &KeyAction{Action: 'a'}, DeleteAction: &KeyAction{Action: 'a'}} }
21522175
;
21532176

21542177
key_update:
@@ -2160,11 +2183,11 @@ key_delete:
21602183
;
21612184

21622185
key_action:
2163-
NO ACTION { $$ = int64('a') }
2164-
| RESTRICT { $$ = int64('r') }
2165-
| CASCADE { $$ = int64('c') }
2166-
| SET NULL_P opt_column_list { $$ = int64('n') }
2167-
| SET DEFAULT opt_column_list { $$ = int64('d') }
2186+
NO ACTION { $$ = &KeyAction{Action: 'a'} }
2187+
| RESTRICT { $$ = &KeyAction{Action: 'r'} }
2188+
| CASCADE { $$ = &KeyAction{Action: 'c'} }
2189+
| SET NULL_P opt_column_list { $$ = &KeyAction{Action: 'n', Cols: $3} }
2190+
| SET DEFAULT opt_column_list { $$ = &KeyAction{Action: 'd', Cols: $3} }
21682191
;
21692192

21702193
opt_c_include:
@@ -4300,6 +4323,7 @@ ViewStmt:
43004323
AS SelectStmt opt_check_option
43014324
{
43024325
rv := makeRangeVar($4).(*nodes.RangeVar)
4326+
rv.Relpersistence = relpersistenceForTemp($2)
43034327
$$ = &nodes.ViewStmt{
43044328
View: rv,
43054329
Aliases: $5,
@@ -4312,6 +4336,7 @@ ViewStmt:
43124336
AS SelectStmt opt_check_option
43134337
{
43144338
rv := makeRangeVar($6).(*nodes.RangeVar)
4339+
rv.Relpersistence = relpersistenceForTemp($4)
43154340
$$ = &nodes.ViewStmt{
43164341
View: rv,
43174342
Aliases: $7,
@@ -4325,6 +4350,7 @@ ViewStmt:
43254350
AS SelectStmt opt_check_option
43264351
{
43274352
rv := makeRangeVar($5).(*nodes.RangeVar)
4353+
rv.Relpersistence = relpersistenceForTemp($2)
43284354
/* Create a WITH RECURSIVE CTE wrapper */
43294355
cte := &nodes.CommonTableExpr{
43304356
Ctename: rv.Relname,
@@ -4358,6 +4384,7 @@ ViewStmt:
43584384
AS SelectStmt opt_check_option
43594385
{
43604386
rv := makeRangeVar($7).(*nodes.RangeVar)
4387+
rv.Relpersistence = relpersistenceForTemp($4)
43614388
cte := &nodes.CommonTableExpr{
43624389
Ctename: rv.Relname,
43634390
Ctequery: $13,
@@ -7712,9 +7739,8 @@ simple_select:
77127739
if $6 != nil {
77137740
n.WhereClause = $6
77147741
}
7715-
if $7 != nil {
7716-
n.GroupClause = $7
7717-
}
7742+
n.GroupClause = $7.List
7743+
n.GroupDistinct = $7.Distinct
77187744
if $8 != nil {
77197745
n.HavingClause = $8
77207746
}
@@ -7738,9 +7764,8 @@ simple_select:
77387764
if $6 != nil {
77397765
n.WhereClause = $6
77407766
}
7741-
if $7 != nil {
7742-
n.GroupClause = $7
7743-
}
7767+
n.GroupClause = $7.List
7768+
n.GroupDistinct = $7.Distinct
77447769
if $8 != nil {
77457770
n.HavingClause = $8
77467771
}
@@ -7823,9 +7848,9 @@ distinct_clause:
78237848
;
78247849

78257850
set_quantifier:
7826-
ALL { $$ = true }
7827-
| DISTINCT { $$ = false }
7828-
| /* EMPTY */ { $$ = false }
7851+
ALL { $$ = SET_QUANTIFIER_ALL }
7852+
| DISTINCT { $$ = SET_QUANTIFIER_DISTINCT }
7853+
| /* EMPTY */ { $$ = SET_QUANTIFIER_DEFAULT }
78297854
;
78307855

78317856
/*****************************************************************************
@@ -8391,8 +8416,17 @@ where_or_current_clause:
83918416

83928417
// GROUP BY clause
83938418
group_clause:
8394-
GROUP_P BY set_quantifier group_by_list { $$ = $4 }
8395-
| /* EMPTY */ { $$ = nil }
8419+
GROUP_P BY set_quantifier group_by_list
8420+
{
8421+
$$ = &GroupClause{
8422+
Distinct: $3 == SET_QUANTIFIER_DISTINCT,
8423+
List: $4,
8424+
}
8425+
}
8426+
| /* EMPTY */
8427+
{
8428+
$$ = &GroupClause{}
8429+
}
83968430
;
83978431

83988432
group_by_list:
@@ -9507,17 +9541,27 @@ func_expr:
95079541
| func_expr_common_subexpr { $$ = $1 }
95089542
| json_aggregate_func filter_clause over_clause
95099543
{
9510-
/* json_aggregate_func returns a node; wrap filter/over if present */
9511-
n := $1
9512-
_ = $2
9513-
_ = $3
9514-
$$ = n
9544+
var c *nodes.JsonAggConstructor
9545+
switch v := $1.(type) {
9546+
case *nodes.JsonObjectAgg:
9547+
c = v.Constructor
9548+
case *nodes.JsonArrayAgg:
9549+
c = v.Constructor
9550+
}
9551+
if c != nil {
9552+
c.Agg_filter = $2
9553+
if $3 != nil {
9554+
c.Over = $3.(*nodes.WindowDef)
9555+
}
9556+
}
9557+
$$ = $1
95159558
}
95169559
;
95179560

95189561
func_expr_windowless:
95199562
func_application { $$ = $1 }
95209563
| func_expr_common_subexpr { $$ = $1 }
9564+
| json_aggregate_func { $$ = $1 }
95219565
;
95229566

95239567
within_group_clause:
@@ -17293,7 +17337,7 @@ func makeListNode(l *nodes.List) nodes.Node {
1729317337
}
1729417338

1729517339
func makeRangeVar(names *nodes.List) nodes.Node {
17296-
rv := &nodes.RangeVar{Inh: true}
17340+
rv := &nodes.RangeVar{Inh: true, Relpersistence: 'p'}
1729717341
if names != nil && len(names.Items) > 0 {
1729817342
switch len(names.Items) {
1729917343
case 1:
@@ -17422,10 +17466,10 @@ func concatLists(a, b *nodes.List) *nodes.List {
1742217466
return result
1742317467
}
1742417468
17425-
func makeSetOp(op nodes.SetOperation, all bool, larg, rarg nodes.Node) nodes.Node {
17469+
func makeSetOp(op nodes.SetOperation, quantifier int64, larg, rarg nodes.Node) nodes.Node {
1742617470
n := &nodes.SelectStmt{
1742717471
Op: op,
17428-
All: all,
17472+
All: quantifier == SET_QUANTIFIER_ALL,
1742917473
Larg: larg.(*nodes.SelectStmt),
1743017474
Rarg: rarg.(*nodes.SelectStmt),
1743117475
}
@@ -17607,6 +17651,34 @@ type SelectLimit struct {
1760717651
LimitOption nodes.LimitOption
1760817652
}
1760917653

17654+
// GroupClause is an internal helper struct for passing GROUP BY clause
17655+
// distinct flag and list through grammar rules (matches PostgreSQL's GroupClause).
17656+
type GroupClause struct {
17657+
Distinct bool
17658+
List *nodes.List
17659+
}
17660+
17661+
// KeyAction is an internal helper struct for passing FK action and column list
17662+
// through grammar rules (matches PostgreSQL's KeyAction).
17663+
type KeyAction struct {
17664+
Action byte
17665+
Cols *nodes.List
17666+
}
17667+
17668+
// KeyActions is an internal helper struct for passing FK update/delete actions
17669+
// through grammar rules (matches PostgreSQL's KeyActions).
17670+
type KeyActions struct {
17671+
UpdateAction *KeyAction
17672+
DeleteAction *KeyAction
17673+
}
17674+
17675+
// SetQuantifier constants matching PostgreSQL's SetQuantifier enum.
17676+
const (
17677+
SET_QUANTIFIER_DEFAULT = int64(0)
17678+
SET_QUANTIFIER_ALL = int64(1)
17679+
SET_QUANTIFIER_DISTINCT = int64(2)
17680+
)
17681+
1761017682
// importQualification is an internal helper struct for passing IMPORT FOREIGN SCHEMA
1761117683
// qualification type and table list through grammar rules.
1761217684
// It implements the nodes.Node interface so it can be passed through %union.
@@ -17687,10 +17759,14 @@ func insertSelectOptions(stmt *nodes.SelectStmt, sortClause *nodes.List, locking
1768717759
// relpersistenceForTemp returns the relpersistence byte based on temp flag.
1768817760
// In PostgreSQL: 'p' = permanent (default), 't' = temporary
1768917761
func relpersistenceForTemp(tempFlag int64) byte {
17690-
if tempFlag == 1 {
17762+
switch tempFlag {
17763+
case 1:
1769117764
return 't'
17765+
case 2:
17766+
return 'u'
17767+
default:
17768+
return 'p'
1769217769
}
17693-
return 'p'
1769417770
}
1769517771

1769617772
// extractArgTypes extracts the type names from a list of FunctionParameter nodes.

0 commit comments

Comments
 (0)