Skip to content

Commit

Permalink
sql: add parsing for interleaved & partitioning with CREATE TABLE AS
Browse files Browse the repository at this point in the history
    CREATE TABLE a (b) INTERLEAVE IN PARENT ... AS ...
    CREATE TABLE a (b) PARTITION BY ... AS ...

The interleave/partition clauses could also plausably go after the AS,
but I felt like this was more parallel to CREATE TABLE where they go
right after the column defs. (Plus there's all sorts of grammar
conflicts with putting it after the AS).

Implementation is blocked on cockroachdb#20940, but in the meantime, this will
return a friendly error message.

Also cleans up some unnecessary function parameters that I noticed were
being passed around.

For cockroachdb#20178

Release note: None
  • Loading branch information
danhhz committed Dec 20, 2017
1 parent 533e942 commit 941e357
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 20 deletions.
2 changes: 1 addition & 1 deletion pkg/ccl/sqlccl/csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func makeSimpleTableDescriptor(
}
}
semaCtx := tree.SemaContext{}
evalCtx := tree.EvalContext{}
evalCtx := tree.EvalContext{Settings: st}
tableDesc, err := sql.MakeTableDesc(
ctx,
nil, /* txn */
Expand Down
4 changes: 2 additions & 2 deletions pkg/sql/alter_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func (n *alterTableNode) startExec(params runParams) error {
return err
}
if d.PartitionBy != nil {
partitioning, _, err := createPartitionedBy(params.ctx, params.p.ExecCfg().Settings,
partitioning, _, err := createPartitionedBy(
params.evalCtx, n.tableDesc, &idx, d.PartitionBy)
if err != nil {
return err
Expand Down Expand Up @@ -445,7 +445,7 @@ func (n *alterTableNode) startExec(params runParams) error {

case *tree.AlterTablePartitionBy:
previousTableDesc := *n.tableDesc
partitioning, _, err := createPartitionedBy(params.ctx, params.p.ExecCfg().Settings,
partitioning, _, err := createPartitionedBy(
&params.p.evalCtx, n.tableDesc, &n.tableDesc.PrimaryIndex, t.PartitionBy)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion pkg/sql/create_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (n *createIndexNode) startExec(params runParams) error {
return err
}
if n.n.PartitionBy != nil {
partitioning, _, err := createPartitionedBy(params.ctx, params.p.ExecCfg().Settings,
partitioning, _, err := createPartitionedBy(
params.evalCtx, n.tableDesc, &indexDesc, n.n.PartitionBy)
if err != nil {
return err
Expand Down
31 changes: 20 additions & 11 deletions pkg/sql/create_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,13 @@ func (n *createTableNode) startExec(params runParams) error {
var affected map[sqlbase.ID]*sqlbase.TableDescriptor
creationTime := params.p.txn.OrigTimestamp()
if n.n.As() {
desc, err = makeTableDescIfAs(n.n, n.dbDesc.ID, id, creationTime, planColumns(n.sourcePlan), privs, &params.p.semaCtx, params.evalCtx)
desc, err = makeTableDescIfAs(
n.n, n.dbDesc.ID, id, creationTime, planColumns(n.sourcePlan), privs, &params.p.semaCtx,
params.evalCtx)
} else {
affected = make(map[sqlbase.ID]*sqlbase.TableDescriptor)
desc, err = params.p.makeTableDesc(params.ctx, n.n, n.dbDesc.ID, id, creationTime, privs, affected)
desc, err = params.p.makeTableDesc(
params.ctx, n.n, n.dbDesc.ID, id, creationTime, privs, affected)
}
if err != nil {
return err
Expand Down Expand Up @@ -817,7 +820,6 @@ func valueEncodePartitionTuple(
}

func createPartitionedByImpl(
ctx context.Context,
evalCtx *tree.EvalContext,
tableDesc *sqlbase.TableDescriptor,
indexDesc *sqlbase.IndexDescriptor,
Expand Down Expand Up @@ -897,7 +899,7 @@ func createPartitionedByImpl(
if l.Subpartition != nil {
newColOffset := colOffset + int(partDesc.NumColumns)
subpartitioning, subCheckExpr, err := createPartitionedByImpl(
ctx, evalCtx, tableDesc, indexDesc, l.Subpartition, newColOffset)
evalCtx, tableDesc, indexDesc, l.Subpartition, newColOffset)
if err != nil {
return partDesc, nil, err
}
Expand Down Expand Up @@ -932,20 +934,18 @@ func createPartitionedByImpl(
// returns a CHECK constraint that can be used to prevent rows that do not
// belong to any partition from being inserted into the index's table.
func createPartitionedBy(
ctx context.Context,
st *cluster.Settings,
evalCtx *tree.EvalContext,
tableDesc *sqlbase.TableDescriptor,
indexDesc *sqlbase.IndexDescriptor,
partBy *tree.PartitionBy,
) (sqlbase.PartitioningDescriptor, *sqlbase.TableDescriptor_CheckConstraint, error) {
if !st.Version.IsMinSupported(cluster.VersionPartitioning) {
if !evalCtx.Settings.Version.IsMinSupported(cluster.VersionPartitioning) {
return sqlbase.PartitioningDescriptor{}, nil,
errors.New("cluster version does not support partitioning")
}

partitioning, checkExpr, err := createPartitionedByImpl(
ctx, evalCtx, tableDesc, indexDesc, partBy, 0 /* colOffset */)
evalCtx, tableDesc, indexDesc, partBy, 0 /* colOffset */)
if err != nil {
return partitioning, nil, err
}
Expand Down Expand Up @@ -1049,6 +1049,15 @@ func makeTableDescIfAs(
desc.AddColumn(*col)
}

if p.Interleave != nil {
return desc, pgerror.UnimplementedWithIssueError(20940,
"INTERLEAVE IN PARENT is currently unsupported with CREATE TABLE AS")
}
if p.PartitionBy != nil {
return desc, pgerror.UnimplementedWithIssueError(20940,
"PARTITION BY is currently unsupported with CREATE TABLE AS")
}

return desc, desc.AllocateIDs()
}

Expand Down Expand Up @@ -1121,7 +1130,7 @@ func MakeTableDesc(
return desc, err
}
if d.PartitionBy != nil {
partitioning, _, err := createPartitionedBy(ctx, st, evalCtx, &desc, &idx, d.PartitionBy)
partitioning, _, err := createPartitionedBy(evalCtx, &desc, &idx, d.PartitionBy)
if err != nil {
return desc, err
}
Expand All @@ -1145,7 +1154,7 @@ func MakeTableDesc(
return desc, err
}
if d.PartitionBy != nil {
partitioning, _, err := createPartitionedBy(ctx, st, evalCtx, &desc, &idx, d.PartitionBy)
partitioning, _, err := createPartitionedBy(evalCtx, &desc, &idx, d.PartitionBy)
if err != nil {
return desc, err
}
Expand Down Expand Up @@ -1208,7 +1217,7 @@ func MakeTableDesc(

if n.PartitionBy != nil {
partitioning, check, err := createPartitionedBy(
ctx, st, evalCtx, &desc, &desc.PrimaryIndex, n.PartitionBy)
evalCtx, &desc, &desc.PrimaryIndex, n.PartitionBy)
if err != nil {
return desc, err
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/interleaved
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,9 @@ END

statement error duplicate key value \(p_id,c_id\)=\(1,1\) violates unique constraint "primary"
INSERT INTO c20067 VALUES (1, 1, 'John Doe')

# Placeholder error so CREATE TABLE AS parses with INTERLEAVE IN PARENT but
# fails with a friendly error

statement error unimplemented: INTERLEAVE IN PARENT is currently unsupported with CREATE TABLE AS
CREATE TABLE err (a) INTERLEAVE IN PARENT p1_1 (i) AS VALUES (1)
5 changes: 4 additions & 1 deletion pkg/sql/logictest/testdata/logic_test/partitioning
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ CREATE TABLE t (a INT, b INT, c INT, PRIMARY KEY (a, b)) PARTITION BY LIST (a) (
PARTITION p1 VALUES IN ($1)
)

statement error unimplemented: PARTITION BY is currently unsupported with CREATE TABLE AS
CREATE TABLE t (a) PARTITION BY LIST (a) (PARTITION p1 VALUES IN (1)) AS VALUES (1)


statement ok
CREATE TABLE ok1 (a INT, b INT, c INT, PRIMARY KEY (a, b)) PARTITION BY LIST (a) (
PARTITION p1 VALUES IN (1),
Expand Down Expand Up @@ -518,7 +522,6 @@ CREATE TABLE IF NOT EXISTS ok12 (a INT, b INT, c INT, PRIMARY KEY (a, b)) PARTIT
PARTITION p2 VALUES IN (2)
)


query TT
SHOW CREATE TABLE ok12
----
Expand Down
4 changes: 4 additions & 0 deletions pkg/sql/parser/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ func TestParse(t *testing.T) {
{`CREATE TABLE a (b INT, c STRING, FAMILY foo (b), FAMILY (c))`},
{`CREATE TABLE a (b INT) INTERLEAVE IN PARENT foo (c, d)`},
{`CREATE TABLE a (b INT) INTERLEAVE IN PARENT foo (c) CASCADE`},
{`CREATE TABLE a (b) INTERLEAVE IN PARENT foo (b) AS VALUES (1)`},
{`CREATE TABLE IF NOT EXISTS a (b) INTERLEAVE IN PARENT foo (b) AS VALUES (1)`},
{`CREATE TABLE a.b (b INT)`},
{`CREATE TABLE IF NOT EXISTS a (b INT)`},

Expand All @@ -199,6 +201,8 @@ func TestParse(t *testing.T) {
},
{`CREATE TABLE a () INTERLEAVE IN PARENT b (c) PARTITION BY LIST (d) (PARTITION e VALUES IN (1))`},
{`CREATE TABLE IF NOT EXISTS a () PARTITION BY LIST (b) (PARTITION c VALUES IN (1))`},
{`CREATE TABLE a (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)) AS VALUES (1)`},
{`CREATE TABLE IF NOT EXISTS a (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)) AS VALUES (1)`},
{`CREATE TABLE a (INDEX (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`},
{`CREATE TABLE a (UNIQUE (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1)))`},
{`CREATE INDEX ON a (b) PARTITION BY LIST (c) (PARTITION d VALUES IN (1))`},
Expand Down
24 changes: 20 additions & 4 deletions pkg/sql/parser/sql.y
Original file line number Diff line number Diff line change
Expand Up @@ -2963,13 +2963,29 @@ create_table_stmt:
}

create_table_as_stmt:
CREATE TABLE any_name opt_column_list AS select_stmt
CREATE TABLE any_name opt_column_list opt_interleave opt_partition_by AS select_stmt
{
$$.val = &tree.CreateTable{Table: $3.normalizableTableName(), IfNotExists: false, Interleave: nil, Defs: nil, AsSource: $6.slct(), AsColumnNames: $4.nameList()}
$$.val = &tree.CreateTable{
Table: $3.normalizableTableName(),
IfNotExists: false,
Interleave: $5.interleave(),
Defs: nil,
AsSource: $8.slct(),
AsColumnNames: $4.nameList(),
PartitionBy: $6.partitionBy(),
}
}
| CREATE TABLE IF NOT EXISTS any_name opt_column_list AS select_stmt
| CREATE TABLE IF NOT EXISTS any_name opt_column_list opt_interleave opt_partition_by AS select_stmt
{
$$.val = &tree.CreateTable{Table: $6.normalizableTableName(), IfNotExists: true, Interleave: nil, Defs: nil, AsSource: $9.slct(), AsColumnNames: $7.nameList()}
$$.val = &tree.CreateTable{
Table: $6.normalizableTableName(),
IfNotExists: true,
Interleave: $8.interleave(),
Defs: nil,
AsSource: $11.slct(),
AsColumnNames: $7.nameList(),
PartitionBy: $9.partitionBy(),
}
}

opt_table_elem_list:
Expand Down
6 changes: 6 additions & 0 deletions pkg/sql/sem/tree/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,12 @@ func (node *CreateTable) Format(buf *bytes.Buffer, f FmtFlags) {
FormatNode(buf, f, node.AsColumnNames)
buf.WriteByte(')')
}
if node.Interleave != nil {
FormatNode(buf, f, node.Interleave)
}
if node.PartitionBy != nil {
FormatNode(buf, f, node.PartitionBy)
}
buf.WriteString(" AS ")
FormatNode(buf, f, node.AsSource)
} else {
Expand Down

0 comments on commit 941e357

Please sign in to comment.