Skip to content

Commit 9ce209f

Browse files
committed
fix type resolution in select of create view stmt
1 parent 09d90ef commit 9ce209f

6 files changed

Lines changed: 95 additions & 22 deletions

File tree

postgres/parser/parser/sql.y

Lines changed: 60 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
@@ -8726,6 +8726,44 @@ create_trigger_stmt:
87268726
Args: $20.nameList(),
87278727
}
87288728
}
8729+
| CREATE opt_constraint TRIGGER trigger_name trigger_time trigger_events ON table_name opt_from_ref_table
8730+
opt_trigger_deferrable_mode opt_trigger_relations opt_for_each opt_when EXECUTE function_or_procedure routine_name '(' sconst_as_name_list ')'
8731+
{
8732+
$$.val = &tree.CreateTrigger{
8733+
Replace: false,
8734+
Constraint: $2.bool(),
8735+
Name: tree.Name($4),
8736+
Time: $5.triggerTime(),
8737+
Events: $6.triggerEvents(),
8738+
OnTable: $8.unresolvedObjectName().ToTableName(),
8739+
RefTable: tree.Name($9),
8740+
Deferrable: $10.triggerDeferrableMode(),
8741+
Relations: $11.triggerRelations(),
8742+
ForEachRow: $12.bool(),
8743+
When: $13.expr(),
8744+
FuncName: $16.unresolvedObjectName(),
8745+
Args: $18.nameList(),
8746+
}
8747+
}
8748+
| CREATE OR REPLACE opt_constraint TRIGGER trigger_name trigger_time trigger_events ON table_name opt_from_ref_table
8749+
opt_trigger_deferrable_mode opt_trigger_relations opt_for_each opt_when EXECUTE function_or_procedure routine_name '(' sconst_as_name_list ')'
8750+
{
8751+
$$.val = &tree.CreateTrigger{
8752+
Replace: true,
8753+
Constraint: $4.bool(),
8754+
Name: tree.Name($6),
8755+
Time: $7.triggerTime(),
8756+
Events: $8.triggerEvents(),
8757+
OnTable: $10.unresolvedObjectName().ToTableName(),
8758+
RefTable: tree.Name($11),
8759+
Deferrable: $12.triggerDeferrableMode(),
8760+
Relations: $13.triggerRelations(),
8761+
ForEachRow: $14.bool(),
8762+
When: $15.expr(),
8763+
FuncName: $18.unresolvedObjectName(),
8764+
Args: $20.nameList(),
8765+
}
8766+
}
87298767

87308768
function_or_procedure:
87318769
FUNCTION
@@ -9573,28 +9611,28 @@ alter_table_all_in_tablespace_stmt:
95739611
}
95749612

95759613
alter_table_parition_stmt:
9576-
ALTER TABLE table_name ATTACH PARTITION partition_name partition_of
9614+
ALTER TABLE relation_expr ATTACH PARTITION partition_name partition_of
95779615
{
95789616
$$.val = &tree.AlterTablePartition{
9579-
Name: $3.unresolvedObjectName(), IfExists: false, Partition: tree.Name($6), Spec: $7.partitionBoundSpec(),
9617+
Name: $3.unresolvedObjectName(), IfExists: false, Partition: $6.unresolvedObjectName(), Spec: $7.partitionBoundSpec(),
95809618
}
95819619
}
9582-
| ALTER TABLE IF EXISTS table_name ATTACH PARTITION partition_name partition_of
9620+
| ALTER TABLE IF EXISTS relation_expr ATTACH PARTITION partition_name partition_of
95839621
{
95849622
$$.val = &tree.AlterTablePartition{
9585-
Name: $5.unresolvedObjectName(), IfExists: true, Partition: tree.Name($8), Spec: $9.partitionBoundSpec(),
9623+
Name: $5.unresolvedObjectName(), IfExists: true, Partition: $8.unresolvedObjectName(), Spec: $9.partitionBoundSpec(),
95869624
}
95879625
}
9588-
| ALTER TABLE table_name DETACH PARTITION partition_name detach_partition_type
9626+
| ALTER TABLE relation_expr DETACH PARTITION partition_name detach_partition_type
95899627
{
95909628
$$.val = &tree.AlterTablePartition{
9591-
Name: $3.unresolvedObjectName(), IfExists: false, Partition: tree.Name($6), IsDetach: true, DetachType: $7.detachPartition(),
9629+
Name: $3.unresolvedObjectName(), IfExists: false, Partition: $6.unresolvedObjectName(), IsDetach: true, DetachType: $7.detachPartition(),
95929630
}
95939631
}
9594-
| ALTER TABLE IF EXISTS table_name DETACH PARTITION partition_name detach_partition_type
9632+
| ALTER TABLE IF EXISTS relation_expr DETACH PARTITION partition_name detach_partition_type
95959633
{
95969634
$$.val = &tree.AlterTablePartition{
9597-
Name: $5.unresolvedObjectName(), IfExists: true, Partition: tree.Name($8), IsDetach: true, DetachType: $9.detachPartition(),
9635+
Name: $5.unresolvedObjectName(), IfExists: true, Partition: $8.unresolvedObjectName(), IsDetach: true, DetachType: $9.detachPartition(),
95989636
}
95999637
}
96009638

@@ -14223,6 +14261,16 @@ name_list:
1422314261
$$.val = append($1.nameList(), tree.Name($3))
1422414262
}
1422514263

14264+
sconst_as_name_list:
14265+
SCONST
14266+
{
14267+
$$.val = tree.NameList{tree.Name($1)}
14268+
}
14269+
| sconst_as_name_list ',' SCONST
14270+
{
14271+
$$.val = append($1.nameList(), tree.Name($3))
14272+
}
14273+
1422614274
sequence_name_list:
1422714275
sequence_name
1422814276
{
@@ -14421,7 +14469,7 @@ cursor_name: name
1442114469

1442214470
tablespace_name: name
1442314471

14424-
partition_name: name
14472+
partition_name: db_object_name
1442514473

1442614474
routine_name: db_object_name
1442714475

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
}

server/analyzer/init.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ 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,
5966
analyzer.Rule{Id: ruleId_ResolveType, Apply: ResolveType},
6067
analyzer.Rule{Id: ruleId_TypeSanitizer, Apply: TypeSanitizer},
@@ -70,11 +77,6 @@ func Init() {
7077
analyzer.Rule{Id: ruleId_ResolveProcedureDefaults, Apply: ResolveProcedureDefaults},
7178
)
7279

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

server/expression/explicit_cast.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ func (c *ExplicitCast) Child() sql.Expression {
7171

7272
// Eval implements the sql.Expression interface.
7373
func (c *ExplicitCast) Eval(ctx *sql.Context, row sql.Row) (any, error) {
74+
if !c.castToType.IsResolvedType() {
75+
return nil, errors.Errorf("cannot call ExplicitCast.Eval with unresolved cast to type: %s", c.castToType.String())
76+
}
77+
7478
val, err := c.sqlChild.Eval(ctx, row)
7579
if err != nil {
7680
return nil, err
@@ -100,7 +104,6 @@ func (c *ExplicitCast) Eval(ctx *sql.Context, row sql.Row) (any, error) {
100104
"EXPLICIT CAST: cast from `%s` to `%s` does not exist: %s",
101105
fromType.String(), c.castToType.String(), c.sqlChild.String(),
102106
)
103-
104107
}
105108
castResult, err := castFunction(ctx, val, c.castToType)
106109
if err != nil {

testing/go/create_view_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ var createViewStmts = []ScriptTest{
100100
Query: "select name from dolt_schemas;",
101101
Expected: []sql.Row{{"testview"}},
102102
},
103-
104103
{
105104
Query: "SET search_path = testschema, myschema;",
106105
Expected: []sql.Row{},
@@ -260,4 +259,22 @@ var createViewStmts = []ScriptTest{
260259
},
261260
},
262261
},
262+
{
263+
Name: "create view with custom type in its select statement",
264+
SetUpScript: []string{
265+
"CREATE TYPE e AS ENUM ('sched', 'busy', 'final', 'help');",
266+
"CREATE TABLE t (id integer NOT NULL, t e);",
267+
"INSERT INTO t VALUES (1, 'busy'), (2, 'final'), (3, 'busy'), (4, 'help');",
268+
},
269+
Assertions: []ScriptTestAssertion{
270+
{
271+
Query: `create view v as select * from t where (t = 'busy'::e);`,
272+
Expected: []sql.Row{},
273+
},
274+
{
275+
Query: `select * from v;`,
276+
Expected: []sql.Row{{1, "busy"}, {3, "busy"}},
277+
},
278+
},
279+
},
263280
}

testing/go/import_dumps_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ func TestImportingDumps(t *testing.T) {
100100
SQLFilename: "Billoxinogen18_ar_backend.sql",
101101
},
102102
{
103+
SetUpScript: []string{
104+
"CREATE USER crisisresolver_visitor WITH SUPERUSER PASSWORD 'password';",
105+
},
103106
Name: "blacktscoder/CrisisSolver",
104107
SQLFilename: "blacktscoder_CrisisSolver.sql",
105108
},

0 commit comments

Comments
 (0)