@@ -69,7 +69,12 @@ func (p *planner) CreateTable(ctx context.Context, n *tree.CreateTable) (planNod
69
69
return nil , err
70
70
}
71
71
72
- numColNames := len (n .AsColumnNames )
72
+ numColNames := 0
73
+ for i := 0 ; i < len (n .Defs ); i ++ {
74
+ if _ , ok := n .Defs [i ].(* tree.ColumnTableDef ); ok {
75
+ numColNames ++
76
+ }
77
+ }
73
78
numColumns := len (planColumns (sourcePlan ))
74
79
if numColNames != 0 && numColNames != numColumns {
75
80
sourcePlan .Close (ctx )
@@ -80,12 +85,22 @@ func (p *planner) CreateTable(ctx context.Context, n *tree.CreateTable) (planNod
80
85
}
81
86
82
87
// Synthesize an input column that provides the default value for the
83
- // hidden rowid column.
88
+ // hidden rowid column, if none of the provided columns are specified
89
+ // as the PRIMARY KEY.
84
90
synthRowID = true
91
+ for _ , def := range n .Defs {
92
+ if d , ok := def .(* tree.ColumnTableDef ); ok && d .PrimaryKey {
93
+ synthRowID = false
94
+ break
95
+ }
96
+ }
85
97
}
86
98
87
99
ct := & createTableNode {n : n , dbDesc : dbDesc , sourcePlan : sourcePlan }
88
100
ct .run .synthRowID = synthRowID
101
+ // This method is only invoked if the heuristic planner was used in the
102
+ // planning stage.
103
+ ct .run .fromHeuristicPlanner = true
89
104
return ct , nil
90
105
}
91
106
@@ -95,10 +110,17 @@ type createTableRun struct {
95
110
autoCommit autoCommitOpt
96
111
97
112
// synthRowID indicates whether an input column needs to be synthesized to
98
- // provide the default value for the hidden rowid column. The optimizer's
99
- // plan already includes this column (so synthRowID is false), whereas the
100
- // heuristic planner's plan does not (so synthRowID is true).
113
+ // provide the default value for the hidden rowid column. The optimizer's plan
114
+ // already includes this column if a user specified PK does not exist (so
115
+ // synthRowID is false), whereas the heuristic planner's plan does not in this
116
+ // case (so synthRowID is true).
101
117
synthRowID bool
118
+
119
+ // fromHeuristicPlanner indicates whether the planning was performed by the
120
+ // heuristic planner instead of the optimizer. This is used to determine
121
+ // whether or not a row_id was synthesized as part of the planning stage, if a
122
+ // user defined PK is not specified.
123
+ fromHeuristicPlanner bool
102
124
}
103
125
104
126
func (n * createTableNode ) startExec (params runParams ) error {
@@ -139,15 +161,18 @@ func (n *createTableNode) startExec(params runParams) error {
139
161
}
140
162
141
163
asCols = planColumns (n .sourcePlan )
142
- if ! n .run .synthRowID {
143
- // rowID column is already present in the input as the last column, so
144
- // ignore it for the purpose of creating column metadata (because
164
+ if ! n .run .fromHeuristicPlanner && ! n .n .AsHasUserSpecifiedPrimaryKey () {
165
+ // rowID column is already present in the input as the last column if it
166
+ // was planned by the optimizer and the user did not specify a PRIMARY
167
+ // KEY. So ignore it for the purpose of creating column metadata (because
145
168
// makeTableDescIfAs does it automatically).
146
169
asCols = asCols [:len (asCols )- 1 ]
147
170
}
148
- desc , err = makeTableDescIfAs (
171
+
172
+ desc , err = makeTableDescIfAs (params ,
149
173
n .n , n .dbDesc .ID , id , creationTime , asCols ,
150
- privs , & params .p .semaCtx , params .p .EvalContext ())
174
+ privs , params .p .EvalContext ())
175
+
151
176
if err != nil {
152
177
return err
153
178
}
@@ -259,9 +284,9 @@ func (n *createTableNode) startExec(params runParams) error {
259
284
return err
260
285
}
261
286
262
- // Prepare the buffer for row values. At this point, one more
263
- // column has been added by ensurePrimaryKey() to the list of
264
- // columns in sourcePlan .
287
+ // Prepare the buffer for row values. At this point, one more column has
288
+ // been added by ensurePrimaryKey() to the list of columns in sourcePlan, if
289
+ // a PRIMARY KEY is not specified by the user .
265
290
rowBuffer := make (tree.Datums , len (desc .Columns ))
266
291
pkColIdx := len (desc .Columns ) - 1
267
292
@@ -975,38 +1000,51 @@ func getFinalSourceQuery(source *tree.Select, evalCtx *tree.EvalContext) string
975
1000
// makeTableDescIfAs is the MakeTableDesc method for when we have a table
976
1001
// that is created with the CREATE AS format.
977
1002
func makeTableDescIfAs (
1003
+ params runParams ,
978
1004
p * tree.CreateTable ,
979
1005
parentID , id sqlbase.ID ,
980
1006
creationTime hlc.Timestamp ,
981
1007
resultColumns []sqlbase.ResultColumn ,
982
1008
privileges * sqlbase.PrivilegeDescriptor ,
983
- semaCtx * tree.SemaContext ,
984
1009
evalContext * tree.EvalContext ,
985
1010
) (desc sqlbase.MutableTableDescriptor , err error ) {
986
- desc = InitTableDescriptor (id , parentID , p .Table .Table (), creationTime , privileges )
987
- desc .CreateQuery = getFinalSourceQuery (p .AsSource , evalContext )
988
-
989
- for i , colRes := range resultColumns {
990
- columnTableDef := tree.ColumnTableDef {Name : tree .Name (colRes .Name ), Type : colRes .Typ }
991
- columnTableDef .Nullable .Nullability = tree .SilentNull
992
- if len (p .AsColumnNames ) > i {
993
- columnTableDef .Name = p .AsColumnNames [i ]
994
- }
995
-
996
- // The new types in the CREATE TABLE AS column specs never use
997
- // SERIAL so we need not process SERIAL types here.
998
- col , _ , _ , err := sqlbase .MakeColumnDefDescs (& columnTableDef , semaCtx )
999
- if err != nil {
1000
- return desc , err
1011
+ colResIndex := 0
1012
+ // TableDefs for a CREATE TABLE ... AS AST node comprise of a ColumnTableDef
1013
+ // for each column, and a ConstraintTableDef for any constraints on those
1014
+ // columns.
1015
+ for _ , defs := range p .Defs {
1016
+ var d * tree.ColumnTableDef
1017
+ var ok bool
1018
+ if d , ok = defs .(* tree.ColumnTableDef ); ok {
1019
+ d .Type = resultColumns [colResIndex ].Typ
1020
+ colResIndex ++
1021
+ }
1022
+ }
1023
+
1024
+ // If there are no TableDefs defined by the parser, then we construct a
1025
+ // ColumnTableDef for each column using resultColumns.
1026
+ if len (p .Defs ) == 0 {
1027
+ for _ , colRes := range resultColumns {
1028
+ var d * tree.ColumnTableDef
1029
+ var ok bool
1030
+ var tableDef tree.TableDef = & tree.ColumnTableDef {Name : tree .Name (colRes .Name ), Type : colRes .Typ }
1031
+ if d , ok = tableDef .(* tree.ColumnTableDef ); ! ok {
1032
+ return desc , errors .Errorf ("failed to cast type to ColumnTableDef\n " )
1033
+ }
1034
+ d .Nullable .Nullability = tree .SilentNull
1035
+ p .Defs = append (p .Defs , tableDef )
1001
1036
}
1002
- desc .AddColumn (col )
1003
1037
}
1004
1038
1005
- // AllocateIDs mutates its receiver. `return desc, desc.AllocateIDs()`
1006
- // happens to work in gc, but does not work in gccgo.
1007
- //
1008
- // See https://github.com/golang/go/issues/23188.
1009
- err = desc .AllocateIDs ()
1039
+ desc , err = makeTableDesc (
1040
+ params ,
1041
+ p ,
1042
+ parentID , id ,
1043
+ creationTime ,
1044
+ privileges ,
1045
+ nil , /* affected */
1046
+ )
1047
+ desc .CreateQuery = getFinalSourceQuery (p .AsSource , evalContext )
1010
1048
return desc , err
1011
1049
}
1012
1050
0 commit comments