Skip to content

Commit

Permalink
sql: support expression indexes in CREATE TABLE ... LIKE
Browse files Browse the repository at this point in the history
This commit adds support for copying table's with expression indexes
with a `CREATE TABLE ... LIKE` statement.

There is no release note because expression-based indexes are not
enabled by default. They require the
experimental_enable_expression_indexes session setting until they are
fully supported.

Release note: None
  • Loading branch information
mgartner committed Jul 14, 2021
1 parent 0e8f534 commit f7cc3e6
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 4 deletions.
17 changes: 14 additions & 3 deletions pkg/sql/create_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -2553,9 +2553,9 @@ func replaceLikeTableOpts(n *tree.CreateTable, params runParams) (tree.TableDefs
// Add all columns. Columns are always added.
for i := range td.Columns {
c := &td.Columns[i]
if c.Hidden {
// Hidden columns automatically get added by the system; we don't need
// to add them ourselves here.
if c.Hidden || c.Inaccessible {
// Hidden and inaccessible columns automatically get added by
// the system; we don't need to add them ourselves here.
continue
}
def := tree.ColumnTableDef{
Expand Down Expand Up @@ -2647,6 +2647,17 @@ func replaceLikeTableOpts(n *tree.CreateTable, params runParams) (tree.TableDefs
Column: tree.Name(name),
Direction: tree.Ascending,
}
col, err := td.FindColumnWithID(idx.GetKeyColumnID(j))
if err != nil {
return nil, err
}
if col.IsExpressionIndexColumn() {
elem.Column = ""
elem.Expr, err = parser.ParseExpr(col.GetComputeExpr())
if err != nil {
return nil, err
}
}
if idx.GetKeyColumnDirection(j) == descpb.IndexDescriptor_DESC {
elem.Direction = tree.Descending
}
Expand Down
128 changes: 127 additions & 1 deletion pkg/sql/logictest/testdata/logic_test/expression_index
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ SELECT * FROM (
# Adding a column with the same name as one of the inaccessible columns created
# for an expression index is allowed after the index has been dropped.
statement ok
ALTER TABLE t ADD COLUMN crd_internal_idx_expr_4 INT
ALTER TABLE t ADD COLUMN crdb_internal_idx_expr_4 INT

statement ok
ALTER TABLE t DROP COLUMN crdb_internal_idx_expr_4

statement error volatile functions are not allowed in index element
CREATE INDEX err ON t ((a + random()::INT))
Expand Down Expand Up @@ -301,6 +304,129 @@ CREATE INDEX err ON other ((t.a + 10))
statement error column \"crdb_internal_idx_expr\" does not exist
SELECT * FROM t WHERE crdb_internal_idx_expr > 0

statement ok
CREATE TABLE src (
k INT PRIMARY KEY,
a INT,
b INT,
j JSON,
comp INT8 AS (1 + 10) VIRTUAL,
INDEX ((a + b)),
INDEX named_idx ((a + 1)),
UNIQUE INDEX ((a + 10)),
INVERTED INDEX ((a + b), (j->'a'))
);
CREATE TABLE copy (LIKE src);
CREATE TABLE copy_generated (LIKE src INCLUDING GENERATED);
CREATE TABLE copy_indexes (LIKE src INCLUDING INDEXES);
CREATE TABLE copy_all (LIKE src INCLUDING ALL)

query T
SELECT create_statement FROM [SHOW CREATE TABLE copy]
----
CREATE TABLE public.copy (
k INT8 NOT NULL,
a INT8 NULL,
b INT8 NULL,
j JSONB NULL,
comp INT8 NULL,
rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
CONSTRAINT "primary" PRIMARY KEY (rowid ASC),
FAMILY "primary" (k, a, b, j, comp, rowid)
)

# Inaccessible expression index columns should not be copied if the indexes are
# not copied. copy should not have any crdb_internal_idx_expr columns.
query I
SELECT count(*) FROM (
SELECT json_array_elements(
crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor, false)->'table'->'columns'
) AS desc FROM system.descriptor WHERE id = 'copy'::REGCLASS
) AS cols WHERE cols.desc->>'name' LIKE 'crdb_internal_idx_expr%'
----
0

query T
SELECT create_statement FROM [SHOW CREATE TABLE copy_generated]
----
CREATE TABLE public.copy_generated (
k INT8 NOT NULL,
a INT8 NULL,
b INT8 NULL,
j JSONB NULL,
comp INT8 NULL AS (1:::INT8 + 10:::INT8) VIRTUAL,
rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(),
CONSTRAINT "primary" PRIMARY KEY (rowid ASC),
FAMILY "primary" (k, a, b, j, rowid)
)

# Inaccessible expression index columns should not be copied if the indexes are
# not copied. copy_generated should not have any crdb_internal_idx_expr columns.
query I
SELECT count(*) FROM (
SELECT json_array_elements(
crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor, false)->'table'->'columns'
) AS desc FROM system.descriptor WHERE id = 'copy_generated'::REGCLASS
) AS cols WHERE cols.desc->>'name' LIKE 'crdb_internal_idx_expr%'
----
0

query T
SELECT create_statement FROM [SHOW CREATE TABLE copy_indexes]
----
CREATE TABLE public.copy_indexes (
k INT8 NOT NULL,
a INT8 NULL,
b INT8 NULL,
j JSONB NULL,
comp INT8 NULL,
CONSTRAINT "primary" PRIMARY KEY (k ASC),
INDEX src_expr_idx ((a + b) ASC),
INDEX named_idx ((a + 1:::INT8) ASC),
UNIQUE INDEX src_expr_key ((a + 10:::INT8) ASC),
INVERTED INDEX src_expr_expr1_idx ((a + b), (j->'a':::STRING)),
FAMILY "primary" (k, a, b, j, comp)
)

# Inaccessible expression index columns should be copied if the indexes are
# copied. copy_indexes should have crdb_internal_idx_expr columns.
query I
SELECT count(*) FROM (
SELECT json_array_elements(
crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor, false)->'table'->'columns'
) AS desc FROM system.descriptor WHERE id = 'copy_indexes'::REGCLASS
) AS cols WHERE cols.desc->>'name' LIKE 'crdb_internal_idx_expr%'
----
5

query T
SELECT create_statement FROM [SHOW CREATE TABLE copy_all]
----
CREATE TABLE public.copy_all (
k INT8 NOT NULL,
a INT8 NULL,
b INT8 NULL,
j JSONB NULL,
comp INT8 NULL AS (1:::INT8 + 10:::INT8) VIRTUAL,
CONSTRAINT "primary" PRIMARY KEY (k ASC),
INDEX src_expr_idx ((a + b) ASC),
INDEX named_idx ((a + 1:::INT8) ASC),
UNIQUE INDEX src_expr_key ((a + 10:::INT8) ASC),
INVERTED INDEX src_expr_expr1_idx ((a + b), (j->'a':::STRING)),
FAMILY "primary" (k, a, b, j)
)

# Inaccessible expression index columns should be copied if the indexes are
# copied. copy_all should have crdb_internal_idx_expr columns.
query I
SELECT count(*) FROM (
SELECT json_array_elements(
crdb_internal.pb_to_json('cockroach.sql.sqlbase.Descriptor', descriptor, false)->'table'->'columns'
) AS desc FROM system.descriptor WHERE id = 'copy_all'::REGCLASS
) AS cols WHERE cols.desc->>'name' LIKE 'crdb_internal_idx_expr%'
----
5

# Test anonymous index name generation.

statement ok
Expand Down

0 comments on commit f7cc3e6

Please sign in to comment.