Skip to content

Commit

Permalink
sql: implement index changes of PARTITION ALL BY on CREATE TABLE
Browse files Browse the repository at this point in the history
Release note (sql change): Implemented PARTITION ALL BY syntax for CREATE
TABLE, which automatically partitions the table, and all indexes, with
the same partitioning scheme.
  • Loading branch information
otan committed Jan 13, 2021
1 parent 70d2bfe commit 0860652
Show file tree
Hide file tree
Showing 3 changed files with 164 additions and 45 deletions.
5 changes: 0 additions & 5 deletions pkg/ccl/logictestccl/testdata/logic_test/partitioning
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ CREATE TABLE t (a INT, b INT, c INT) PARTITION BY LIST (a) (
PARTITION p1 VALUES IN (0)
)

statement error PARTITION ALL BY not yet implemented
CREATE TABLE t (a INT, b INT) PARTITION ALL BY LIST (b) (
PARTITION p1 VALUES IN (0)
)

statement error declared partition columns \(a, b, c\) exceed the number of columns in index being partitioned \(a, b\)
CREATE TABLE t (a INT, b INT, c INT, PRIMARY KEY (a, b)) PARTITION BY LIST (a, b, c) (
PARTITION p1 VALUES IN (0)
Expand Down
107 changes: 102 additions & 5 deletions pkg/ccl/logictestccl/testdata/logic_test/partitioning_implicit
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
# LogicTest: local

statement error declared partition columns \(partition_by\) do not match first 1 columns in index being partitioned \(a\)
CREATE TABLE t (
pk INT PRIMARY KEY,
partition_by int,
a INT,
INDEX (a) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN (1),
PARTITION two VALUES IN (2)
)
)

statement error PARTITION ALL BY LIST/RANGE is currently experimental
CREATE TABLE public.t (
pk int PRIMARY KEY,
partition_by int
) PARTITION ALL BY LIST (partition_by) (
PARTITION one VALUES IN (1),
PARTITION two VALUES IN (2)
)

statement ok
SET experimental_enable_implicit_column_partitioning = true

Expand Down Expand Up @@ -113,11 +133,11 @@ WHERE indrelid = (SELECT oid FROM pg_class WHERE relname = 't')
ORDER BY 1,2,3
----
indexrelid indrelid indkey indclass indoption indcollation
450499960 55 3 0 2 0
450499961 55 4 0 2 0
450499963 55 1 0 2 0
450499966 55 2 3 4 0 0 0 2 2 2 0 0 0
450499967 55 5 0 2 0
969972496 57 2 3 4 0 0 0 2 2 2 0 0 0
969972497 57 5 0 2 0
969972501 57 1 0 2 0
969972502 57 3 0 2 0
969972503 57 4 0 2 0

query TTB colnames
SELECT index_name, column_name, implicit FROM crdb_internal.index_columns
Expand Down Expand Up @@ -161,3 +181,80 @@ statement error cannot ALTER TABLE PARTITION BY on table which already has impli
ALTER TABLE t PARTITION BY LIST (a) (
PARTITION pk_implicit VALUES IN (1)
)

statement error PARTITION ALL BY not yet implemented
ALTER TABLE t PARTITION ALL BY LIST (a) (
PARTITION pk_implicit VALUES IN (1)
)

statement ok
DROP TABLE t

statement error cannot define PARTITION BY on an index if the table has a PARTITION ALL BY definition
CREATE TABLE public.t (
pk int PRIMARY KEY,
partition_by int,
a int,
INDEX(a) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN (1)
)
) PARTITION ALL BY LIST (partition_by) (
PARTITION one VALUES IN (1),
PARTITION two VALUES IN (2)
)

statement error cannot define PARTITION BY on an unique constraint if the table has a PARTITION ALL BY definition
CREATE TABLE public.t (
pk int PRIMARY KEY,
partition_by int,
a int,
UNIQUE(a) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN (1)
)
) PARTITION ALL BY LIST (partition_by) (
PARTITION one VALUES IN (1),
PARTITION two VALUES IN (2)
)

statement ok
CREATE TABLE public.t (
pk int PRIMARY KEY,
partition_by int,
a int,
b int,
c int,
d int,
INDEX (a),
UNIQUE (b),
FAMILY (pk, partition_by, a, b, c, d)
) PARTITION ALL BY LIST (partition_by) (
PARTITION one VALUES IN (1),
PARTITION two VALUES IN (2)
)

# TODO(#58878): PARTITION BY should be hidden for index definitions.
query T
SELECT create_statement FROM [SHOW CREATE TABLE t]
----
CREATE TABLE public.t (
pk INT8 NOT NULL,
partition_by INT8 NULL,
a INT8 NULL,
b INT8 NULL,
c INT8 NULL,
d INT8 NULL,
CONSTRAINT "primary" PRIMARY KEY (pk ASC),
INDEX t_a_idx (a ASC) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN ((1)),
PARTITION two VALUES IN ((2))
),
UNIQUE INDEX t_b_key (b ASC) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN ((1)),
PARTITION two VALUES IN ((2))
),
FAMILY fam_0_pk_partition_by_a_b_c_d (pk, partition_by, a, b, c, d)
) PARTITION BY LIST (partition_by) (
PARTITION one VALUES IN ((1)),
PARTITION two VALUES IN ((2))
)
-- Warning: Partitioned table with no zone configurations.
97 changes: 62 additions & 35 deletions pkg/sql/create_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,21 @@ func NewTableDesc(
}
return nil
}

var partitionByAll *tree.PartitionBy
if n.PartitionByTable != nil && n.PartitionByTable.All {
if !evalCtx.SessionData.ImplicitColumnPartitioningEnabled {
return nil, errors.WithHint(
pgerror.New(
pgcode.FeatureNotSupported,
"PARTITION ALL BY LIST/RANGE is currently experimental",
),
"to enable, use SET experimental_enable_implicit_column_partitioning = true",
)
}
partitionByAll = n.PartitionByTable.PartitionBy
}

idxValidator := schemaexpr.MakeIndexPredicateValidator(ctx, n.Table, &desc, semaCtx)
for _, def := range n.Defs {
switch d := def.(type) {
Expand Down Expand Up @@ -1561,14 +1576,23 @@ func NewTableDesc(
idx.GeoConfig = *geoindex.DefaultGeographyIndexConfig()
}
}
if d.PartitionByIndex.ContainsPartitions() {
if d.PartitionByIndex.ContainsPartitions() || partitionByAll != nil {
partitionBy := partitionByAll
if partitionByAll == nil {
partitionBy = d.PartitionByIndex.PartitionBy
} else if d.PartitionByIndex.ContainsPartitions() {
return nil, pgerror.New(
pgcode.FeatureNotSupported,
"cannot define PARTITION BY on an index if the table has a PARTITION ALL BY definition",
)
}
var numImplicitColumns int
var err error
idx, numImplicitColumns, err = detectImplicitPartitionColumns(
evalCtx,
&desc,
idx,
d.PartitionByIndex.PartitionBy,
partitionBy,
)
if err != nil {
return nil, err
Expand All @@ -1580,7 +1604,7 @@ func NewTableDesc(
&desc,
&idx,
numImplicitColumns,
d.PartitionByIndex.PartitionBy,
partitionBy,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1633,14 +1657,24 @@ func NewTableDesc(
if err := idx.FillColumns(d.Columns); err != nil {
return nil, err
}
if d.PartitionByIndex.ContainsPartitions() {
if d.PartitionByIndex.ContainsPartitions() || partitionByAll != nil {
partitionBy := partitionByAll
if partitionByAll == nil {
partitionBy = d.PartitionByIndex.PartitionBy
} else if d.PartitionByIndex.ContainsPartitions() {
return nil, pgerror.New(
pgcode.FeatureNotSupported,
"cannot define PARTITION BY on an unique constraint if the table has a PARTITION ALL BY definition",
)
}

var numImplicitColumns int
var err error
idx, numImplicitColumns, err = detectImplicitPartitionColumns(
evalCtx,
&desc,
idx,
d.PartitionByIndex.PartitionBy,
partitionBy,
)
if err != nil {
return nil, err
Expand All @@ -1652,7 +1686,7 @@ func NewTableDesc(
&desc,
&idx,
numImplicitColumns,
d.PartitionByIndex.PartitionBy,
partitionBy,
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -1759,37 +1793,30 @@ func NewTableDesc(
}
}

// Do not use ContainsPartitions() for this check, as we may have to do something special for
// PARTITION BY NOTHING.
if n.PartitionByTable != nil {
if n.PartitionByTable.All {
return nil, unimplemented.New("CREATE TABLE PARTITION ALL BY", "PARTITION ALL BY not yet implemented")
if n.PartitionByTable.ContainsPartitions() {
newPrimaryIndex, numImplicitColumns, err := detectImplicitPartitionColumns(
evalCtx,
&desc,
*desc.GetPrimaryIndex().IndexDesc(),
n.PartitionByTable.PartitionBy,
)
if err != nil {
return nil, err
}
if n.PartitionByTable.PartitionBy != nil {
newPrimaryIndex, numImplicitColumns, err := detectImplicitPartitionColumns(
evalCtx,
&desc,
*desc.GetPrimaryIndex().IndexDesc(),
n.PartitionByTable.PartitionBy,
)
if err != nil {
return nil, err
}
partitioning, err := CreatePartitioning(
ctx,
st,
evalCtx,
&desc,
&newPrimaryIndex,
numImplicitColumns,
n.PartitionByTable.PartitionBy,
)
if err != nil {
return nil, err
}
newPrimaryIndex.Partitioning = partitioning
desc.SetPrimaryIndex(newPrimaryIndex)
partitioning, err := CreatePartitioning(
ctx,
st,
evalCtx,
&desc,
&newPrimaryIndex,
numImplicitColumns,
n.PartitionByTable.PartitionBy,
)
if err != nil {
return nil, err
}
newPrimaryIndex.Partitioning = partitioning
desc.SetPrimaryIndex(newPrimaryIndex)
}

// Once all the IDs have been allocated, we can add the Sequence dependencies
Expand Down

0 comments on commit 0860652

Please sign in to comment.