Skip to content

Commit f3a4abb

Browse files
authored
Merge pull request #2558 from dolthub/jennifer/fix
fix type resolution in select of create view stmt
2 parents f5bf7f4 + a57625e commit f3a4abb

21 files changed

+422
-83
lines changed

postgres/parser/parser/parse.go

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,15 @@ func (p *Parser) parseOneWithDepth(depth int, sql string) (Statement, error) {
129129
return stmts[0], nil
130130
}
131131

132-
func (p *Parser) scanOneStmt() (sql string, tokens []sqlSymType, done bool) {
132+
func (p *Parser) scanOneStmt(parse func(sqlStr string, tokens []sqlSymType) error) bool {
133133
var lval sqlSymType
134-
tokens = p.tokBuf[:0]
134+
tokens := p.tokBuf[:0]
135135

136136
// Scan the first token.
137137
for {
138138
p.scanner.scan(&lval)
139139
if lval.id == 0 {
140-
return "", nil, true
140+
return true
141141
}
142142
if lval.id != ';' {
143143
break
@@ -150,12 +150,21 @@ func (p *Parser) scanOneStmt() (sql string, tokens []sqlSymType, done bool) {
150150
tokens = append(tokens, lval)
151151
for {
152152
if lval.id == ERROR {
153-
return p.scanner.in[startPos:], tokens, true
153+
_ = parse(p.scanner.in[startPos:], tokens)
154+
return true
154155
}
155156
posBeforeScan := p.scanner.pos
156157
p.scanner.scan(&lval)
157158
if lval.id == 0 || lval.id == ';' {
158-
return p.scanner.in[startPos:posBeforeScan], tokens, (lval.id == 0)
159+
err := parse(p.scanner.in[startPos:posBeforeScan], tokens)
160+
if lval.id == 0 || (err != nil && !strings.Contains(err.Error(), "EOF")) {
161+
// done scanning all statements OR due to non EOF error
162+
return true
163+
} else if err == nil {
164+
// done scanning single statement
165+
return false
166+
}
167+
// continue scanning if it's EOF error
159168
}
160169
lval.pos -= startPos
161170
tokens = append(tokens, lval)
@@ -166,19 +175,27 @@ func (p *Parser) parseWithDepth(depth int, sql string, nakedIntType *types.T) (S
166175
stmts := Statements(p.stmtBuf[:0])
167176
p.scanner.init(sql)
168177
defer p.scanner.cleanup()
178+
var err error
169179
for {
170-
sql, tokens, done := p.scanOneStmt()
171-
stmt, err := p.parse(depth+1, sql, tokens, nakedIntType)
172-
if err != nil {
173-
return nil, err
174-
}
175-
if stmt.AST != nil {
176-
stmts = append(stmts, stmt)
177-
}
180+
done := p.scanOneStmt(func(sqlStr string, tokens []sqlSymType) error {
181+
var stmt Statement
182+
stmt, err = p.parse(depth+1, sqlStr, tokens, nakedIntType)
183+
if err != nil {
184+
// if it's EOF syntax error, try running again
185+
return err
186+
}
187+
if stmt.AST != nil {
188+
stmts = append(stmts, stmt)
189+
}
190+
return nil
191+
})
178192
if done {
179193
break
180194
}
181195
}
196+
if err != nil {
197+
return nil, err
198+
}
182199
return stmts, nil
183200
}
184201

@@ -259,7 +276,9 @@ func HasMultipleStatements(sql string) bool {
259276
defer p.scanner.cleanup()
260277
count := 0
261278
for {
262-
_, _, done := p.scanOneStmt()
279+
done := p.scanOneStmt(func(sqlStr string, tokens []sqlSymType) error {
280+
return nil
281+
})
263282
if done {
264283
break
265284
}

postgres/parser/parser/sql.y

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,11 +1153,11 @@ func (u *sqlSymUnion) vacuumTableAndColsList() tree.VacuumTableAndColsList {
11531153
%type <str> table_alias_name constraint_name target_name opt_from_ref_table
11541154
%type <*tree.UnresolvedObjectName> collation_name
11551155
%type <str> db_object_name_component
1156-
%type <*tree.UnresolvedObjectName> table_name standalone_index_name sequence_name type_name routine_name aggregate_name
1156+
%type <*tree.UnresolvedObjectName> table_name standalone_index_name sequence_name type_name routine_name aggregate_name partition_name
11571157
%type <*tree.UnresolvedObjectName> view_name db_object_name simple_db_object_name complex_db_object_name opt_collate
11581158
%type <*tree.UnresolvedObjectName> db_object_name_no_keywords simple_db_object_name_no_keywords complex_db_object_name_no_keywords
11591159
%type <[]*tree.UnresolvedObjectName> type_name_list sequence_name_list
1160-
%type <str> schema_name opt_schema_name opt_schema opt_version tablespace_name partition_name
1160+
%type <str> schema_name opt_schema_name opt_schema opt_version tablespace_name
11611161
%type <[]string> schema_name_list role_spec_list opt_role_list opt_owned_by_list
11621162
%type <*tree.UnresolvedName> table_pattern complex_table_pattern
11631163
%type <*tree.UnresolvedName> column_path prefixed_column_path column_path_with_star
@@ -1201,7 +1201,7 @@ func (u *sqlSymUnion) vacuumTableAndColsList() tree.VacuumTableAndColsList {
12011201
%type <[]*tree.Order> sortby_list
12021202
%type <tree.IndexParams> constraint_index_params
12031203
%type <tree.IndexElemList> index_params index_params_name_only opt_index_params_name_only opt_include_index_cols partition_index_params exclude_elems
1204-
%type <tree.NameList> name_list opt_name_list privilege_list
1204+
%type <tree.NameList> name_list opt_name_list privilege_list sconst_as_name_list
12051205
%type <[]int32> opt_array_bounds
12061206
%type <tree.From> from_clause
12071207
%type <tree.TableExprs> from_list opt_from_list
@@ -4611,6 +4611,10 @@ begin_end_block:
46114611
{
46124612
$$.val = &tree.BeginEndBlock{Statements: $3.stmts()}
46134613
}
4614+
| BEGIN ATOMIC RETURN a_expr ';' END
4615+
{
4616+
$$.val = &tree.BeginEndBlock{Statements: []tree.Statement{&tree.Return{Expr: $4.expr()}}}
4617+
}
46144618

46154619
opt_schema:
46164620
/* EMPTY */
@@ -8726,6 +8730,44 @@ create_trigger_stmt:
87268730
Args: $20.nameList(),
87278731
}
87288732
}
8733+
| CREATE opt_constraint TRIGGER trigger_name trigger_time trigger_events ON table_name opt_from_ref_table
8734+
opt_trigger_deferrable_mode opt_trigger_relations opt_for_each opt_when EXECUTE function_or_procedure routine_name '(' sconst_as_name_list ')'
8735+
{
8736+
$$.val = &tree.CreateTrigger{
8737+
Replace: false,
8738+
Constraint: $2.bool(),
8739+
Name: tree.Name($4),
8740+
Time: $5.triggerTime(),
8741+
Events: $6.triggerEvents(),
8742+
OnTable: $8.unresolvedObjectName().ToTableName(),
8743+
RefTable: tree.Name($9),
8744+
Deferrable: $10.triggerDeferrableMode(),
8745+
Relations: $11.triggerRelations(),
8746+
ForEachRow: $12.bool(),
8747+
When: $13.expr(),
8748+
FuncName: $16.unresolvedObjectName(),
8749+
Args: $18.nameList(),
8750+
}
8751+
}
8752+
| CREATE OR REPLACE opt_constraint TRIGGER trigger_name trigger_time trigger_events ON table_name opt_from_ref_table
8753+
opt_trigger_deferrable_mode opt_trigger_relations opt_for_each opt_when EXECUTE function_or_procedure routine_name '(' sconst_as_name_list ')'
8754+
{
8755+
$$.val = &tree.CreateTrigger{
8756+
Replace: true,
8757+
Constraint: $4.bool(),
8758+
Name: tree.Name($6),
8759+
Time: $7.triggerTime(),
8760+
Events: $8.triggerEvents(),
8761+
OnTable: $10.unresolvedObjectName().ToTableName(),
8762+
RefTable: tree.Name($11),
8763+
Deferrable: $12.triggerDeferrableMode(),
8764+
Relations: $13.triggerRelations(),
8765+
ForEachRow: $14.bool(),
8766+
When: $15.expr(),
8767+
FuncName: $18.unresolvedObjectName(),
8768+
Args: $20.nameList(),
8769+
}
8770+
}
87298771

87308772
function_or_procedure:
87318773
FUNCTION
@@ -9573,28 +9615,28 @@ alter_table_all_in_tablespace_stmt:
95739615
}
95749616

95759617
alter_table_parition_stmt:
9576-
ALTER TABLE table_name ATTACH PARTITION partition_name partition_of
9618+
ALTER TABLE relation_expr ATTACH PARTITION partition_name partition_of
95779619
{
95789620
$$.val = &tree.AlterTablePartition{
9579-
Name: $3.unresolvedObjectName(), IfExists: false, Partition: tree.Name($6), Spec: $7.partitionBoundSpec(),
9621+
Name: $3.unresolvedObjectName(), IfExists: false, Partition: $6.unresolvedObjectName(), Spec: $7.partitionBoundSpec(),
95809622
}
95819623
}
9582-
| ALTER TABLE IF EXISTS table_name ATTACH PARTITION partition_name partition_of
9624+
| ALTER TABLE IF EXISTS relation_expr ATTACH PARTITION partition_name partition_of
95839625
{
95849626
$$.val = &tree.AlterTablePartition{
9585-
Name: $5.unresolvedObjectName(), IfExists: true, Partition: tree.Name($8), Spec: $9.partitionBoundSpec(),
9627+
Name: $5.unresolvedObjectName(), IfExists: true, Partition: $8.unresolvedObjectName(), Spec: $9.partitionBoundSpec(),
95869628
}
95879629
}
9588-
| ALTER TABLE table_name DETACH PARTITION partition_name detach_partition_type
9630+
| ALTER TABLE relation_expr DETACH PARTITION partition_name detach_partition_type
95899631
{
95909632
$$.val = &tree.AlterTablePartition{
9591-
Name: $3.unresolvedObjectName(), IfExists: false, Partition: tree.Name($6), IsDetach: true, DetachType: $7.detachPartition(),
9633+
Name: $3.unresolvedObjectName(), IfExists: false, Partition: $6.unresolvedObjectName(), IsDetach: true, DetachType: $7.detachPartition(),
95929634
}
95939635
}
9594-
| ALTER TABLE IF EXISTS table_name DETACH PARTITION partition_name detach_partition_type
9636+
| ALTER TABLE IF EXISTS relation_expr DETACH PARTITION partition_name detach_partition_type
95959637
{
95969638
$$.val = &tree.AlterTablePartition{
9597-
Name: $5.unresolvedObjectName(), IfExists: true, Partition: tree.Name($8), IsDetach: true, DetachType: $9.detachPartition(),
9639+
Name: $5.unresolvedObjectName(), IfExists: true, Partition: $8.unresolvedObjectName(), IsDetach: true, DetachType: $9.detachPartition(),
95989640
}
95999641
}
96009642

@@ -14223,6 +14265,16 @@ name_list:
1422314265
$$.val = append($1.nameList(), tree.Name($3))
1422414266
}
1422514267

14268+
sconst_as_name_list:
14269+
SCONST
14270+
{
14271+
$$.val = tree.NameList{tree.Name($1)}
14272+
}
14273+
| sconst_as_name_list ',' SCONST
14274+
{
14275+
$$.val = append($1.nameList(), tree.Name($3))
14276+
}
14277+
1422614278
sequence_name_list:
1422714279
sequence_name
1422814280
{
@@ -14421,7 +14473,7 @@ cursor_name: name
1442114473

1442214474
tablespace_name: name
1442314475

14424-
partition_name: name
14476+
partition_name: db_object_name
1442514477

1442614478
routine_name: db_object_name
1442714479

postgres/parser/sem/tree/alter_table.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ var _ Statement = &AlterTablePartition{}
951951
type AlterTablePartition struct {
952952
Name *UnresolvedObjectName
953953
IfExists bool
954-
Partition Name
954+
Partition *UnresolvedObjectName
955955
Spec PartitionBoundSpec
956956
IsDetach bool
957957
DetachType DetachPartition
@@ -966,7 +966,7 @@ func (node *AlterTablePartition) Format(ctx *FmtCtx) {
966966
node.Name.Format(ctx)
967967
if node.IsDetach {
968968
ctx.WriteString(" DETACH PARTITION ")
969-
ctx.FormatNode(&node.Partition)
969+
node.Name.Format(ctx)
970970
switch node.DetachType {
971971
case DetachPartitionNone:
972972
case DetachPartitionConcurrently:
@@ -976,7 +976,7 @@ func (node *AlterTablePartition) Format(ctx *FmtCtx) {
976976
}
977977
} else {
978978
ctx.WriteString(" ATTACH PARTITION ")
979-
ctx.FormatNode(&node.Partition)
979+
node.Name.Format(ctx)
980980
ctx.WriteByte(' ')
981981
ctx.FormatNode(&node.Spec)
982982
}

postgres/parser/sem/tree/create_function.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,12 @@ type BeginEndBlock struct {
280280
}
281281

282282
func (node *BeginEndBlock) Format(ctx *FmtCtx) {
283-
ctx.WriteString("BEGIN ATOMIC")
284-
for i, s := range node.Statements {
285-
if i != 0 {
286-
ctx.WriteString("; ")
287-
}
283+
ctx.WriteString("BEGIN ATOMIC ")
284+
for _, s := range node.Statements {
288285
ctx.FormatNode(s)
286+
ctx.WriteString("; ")
289287
}
290-
ctx.WriteString(" END")
288+
ctx.WriteString("END")
291289
}
292290

293291
var _ Statement = &Return{}

server/analyzer/init.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@ const (
5555

5656
// Init adds additional rules to the analyzer to handle Doltgres-specific functionality.
5757
func Init() {
58+
// OnceBeforeDefault runs before AlwaysBeforeDefault in GMS
59+
analyzer.OnceBeforeDefault = append([]analyzer.Rule{
60+
{Id: ruleId_ResolveType, Apply: ResolveType}, // ResolveType rule must run before simplifyFilters rule in GMS
61+
{Id: ruleId_ApplyTablesForAnalyzeAllTables, Apply: applyTablesForAnalyzeAllTables},
62+
{Id: ruleId_ConvertDropPrimaryKeyConstraint, Apply: convertDropPrimaryKeyConstraint}},
63+
analyzer.OnceBeforeDefault...)
64+
5865
analyzer.AlwaysBeforeDefault = append(analyzer.AlwaysBeforeDefault,
66+
// ResolveType rule must run in this batch in addition to OnceBeforeDefault batch
67+
// because of custom batch set optimization in GMS skipping OnceBeforeDefault batch for some nodes.
5968
analyzer.Rule{Id: ruleId_ResolveType, Apply: ResolveType},
6069
analyzer.Rule{Id: ruleId_TypeSanitizer, Apply: TypeSanitizer},
6170
analyzer.Rule{Id: ruleId_ResolveValuesTypes, Apply: ResolveValuesTypes},
@@ -70,11 +79,6 @@ func Init() {
7079
analyzer.Rule{Id: ruleId_ResolveProcedureDefaults, Apply: ResolveProcedureDefaults},
7180
)
7281

73-
analyzer.OnceBeforeDefault = append([]analyzer.Rule{
74-
{Id: ruleId_ApplyTablesForAnalyzeAllTables, Apply: applyTablesForAnalyzeAllTables},
75-
{Id: ruleId_ConvertDropPrimaryKeyConstraint, Apply: convertDropPrimaryKeyConstraint}},
76-
analyzer.OnceBeforeDefault...)
77-
7882
// We remove several validation rules and substitute our own
7983
analyzer.OnceBeforeDefault = insertAnalyzerRules(analyzer.OnceBeforeDefault, analyzer.ValidateCreateTableId, true,
8084
analyzer.Rule{Id: ruleId_ValidateCreateTable, Apply: validateCreateTable})

server/ast/convert.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ func Convert(postgresStmt parser.Statement) (vitess.Statement, error) {
191191
return nodeReparentDatabase(ctx, stmt)
192192
case *tree.Restore:
193193
return nodeRestore(ctx, stmt)
194+
case *tree.Return:
195+
return nodeReturn(ctx, stmt)
194196
case *tree.Revoke:
195197
return nodeRevoke(ctx, stmt)
196198
case *tree.RevokeRole:

0 commit comments

Comments
 (0)