From cfa32f104dd982bf848a057fa4758aed558da598 Mon Sep 17 00:00:00 2001 From: Marcus Gartner Date: Thu, 15 Dec 2022 17:09:19 -0500 Subject: [PATCH] sql: deprecate ordinal column references This commit disallows ordinal column references by default. Any statements using them will result in an error. The session setting `allow_ordinal_column_references` can be set to true to revert to previous behavior. Note that numeric tuple indexing (e.g., `SELECT ((1,2,3)).@2`) is still allowed. This deprecation is motivated by the inconsistent and surprising behavior that ordinal column references provide. Ordinal column references (e.g., `SELECT @1 FROM t`) are a vestigial and undocumented feature originally motivated to aid the heuristic planner. The PR that added them, #10729, discourages their use by users because "they are not robust against schema changes". It also points out a subtle difference between ordinal column references and SQL standard ordinals that could confuse users. As an example, the following statements are not equivalent: ```sql SELECT @2 FROM t ORDER BY @1; SELECT @2 FROM t ORDER BY 1; ``` In the current implementation, an ordinal column reference `@n` resolves to the n-th column in the current scope's slice of columns. This has several implications: 1. Ordinal columns can refer to any column, not just columns of data sources in `FROM` clauses, as was originally intended. This makes it hard to reason about the resolution of an ordinal column reference. For example, it's somewhat surprising that the result of the `SELECT` below is not `(10, 1)`. ``` CREATE TABLE t (a INT, b INT); INSERT INTO t VALUES (1, 10); SELECT @2, @1 FROM (SELECT @2, @1 FROM t); ?column? | ?column? -----------+----------- 1 | 10 (1 row) ``` 2. The ordering of columns in the scope's slice is not guaranteed to be consistent, so any reasonable ordinal column resolution occurs more-or-less by chance. As an example of unexpected behavior, consider: ``` CREATE TABLE t (a INT PRIMARY KEY, INDEX ((a+10))); INSERT INTO t(a) VALUES (1); ALTER TABLE t ADD COLUMN b INT; SELECT @1, @2 FROM t; ?column? | ?column? -----------+----------- 1 | 11 (1 row) ``` Most users would expect the result of the `SELECT` statement to be `(1, NULL)` because `@1` should resolve to `a` and `@2` should resolve to `b`. Instead, the ordinal column reference `@2` circumvents logic that keeps inaccessible columns from being referenced, and resolves to the virtual computed column backing the secondary index. Epic: None Release note (sql change): Ordinal column references (e.g., `SELECT @1, @2 FROM t`) are now deprecated. By default, statements using this syntax will now result in an error. They can be allowed using the session setting `SET allow_ordinal_column_references=true`. Support for ordinal column references is scheduled to be removed in version 23.2. --- .../backup-restore/user-defined-functions | 8 +-- .../partitioning_hash_sharded_index | 12 ++-- .../regional_by_row_hash_sharded_index | 12 ++-- pkg/cli/clisqlshell/sql_test.go | 4 +- pkg/cli/interactive_tests/test_notice.tcl | 2 +- .../test_url_db_override.tcl | 12 ++-- pkg/sql/delegate/show_syntax.go | 8 +-- pkg/sql/exec_util.go | 4 ++ .../testdata/logic_test/alter_primary_key | 12 ++-- pkg/sql/logictest/testdata/logic_test/array | 2 +- .../testdata/logic_test/create_index | 2 +- .../testdata/logic_test/create_table | 4 +- .../testdata/logic_test/hash_sharded_index | 10 +-- .../testdata/logic_test/information_schema | 1 + .../testdata/logic_test/inverted_index | 2 +- .../testdata/logic_test/name_escapes | 10 ++- .../testdata/logic_test/numeric_references | 2 +- .../logictest/testdata/logic_test/order_by | 2 +- .../testdata/logic_test/ordinal_references | 3 + .../logictest/testdata/logic_test/pg_catalog | 3 + .../logictest/testdata/logic_test/show_create | 4 +- .../logictest/testdata/logic_test/show_source | 1 + .../testdata/logic_test/statement_source | 2 +- pkg/sql/logictest/testdata/logic_test/udf | 62 +++++++++---------- .../opt/exec/execbuilder/testdata/aggregate | 6 ++ pkg/sql/opt/exec/execbuilder/testdata/explain | 9 ++- .../execbuilder/testdata/hash_sharded_index | 2 +- pkg/sql/opt/exec/execbuilder/testdata/orderby | 6 ++ pkg/sql/opt/exec/execbuilder/testdata/spool | 12 ++-- pkg/sql/opt/memo/memo.go | 5 +- pkg/sql/opt/memo/memo_test.go | 6 ++ pkg/sql/opt/optbuilder/scalar.go | 10 +++ pkg/sql/opt/optbuilder/testdata/orderby | 12 +++- pkg/sql/opt/optbuilder/testdata/select | 5 ++ pkg/sql/opt/optbuilder/testdata/sequence | 5 ++ .../local_only_session_data.proto | 3 + pkg/sql/vars.go | 15 +++++ 37 files changed, 179 insertions(+), 101 deletions(-) diff --git a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions index c595d1a91eb4..8c5131fd28a8 100644 --- a/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions +++ b/pkg/ccl/backupccl/testdata/backup-restore/user-defined-functions @@ -50,7 +50,7 @@ db1 sc2 tbl2 table false db1 sc2 f2 function false query-sql -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f1] +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f1] ---- CREATE FUNCTION sc1.f1(IN a db1.sc1.enum1) RETURNS INT8 @@ -85,7 +85,7 @@ USE db1_new # 2. db name in qualified name is rewritten. # 3. sequence id is rewritten so that sequence name is deserialized correctly. query-sql -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f1] +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f1] ---- CREATE FUNCTION sc1.f1(IN a db1_new.sc1.enum1) RETURNS INT8 @@ -200,7 +200,7 @@ db1 sc2 tbl2 table true db1 sc2 f2 function true query-sql -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f1] +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f1] ---- CREATE FUNCTION sc1.f1(IN a db1.sc1.enum1) RETURNS INT8 @@ -236,7 +236,7 @@ USE db1 # 2. db name in qualified name is rewritten. # 3. sequence id is rewritten so that sequence name is deserialized correctly. query-sql -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f1] +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f1] ---- CREATE FUNCTION sc1.f1(IN a db1.sc1.enum1) RETURNS INT8 diff --git a/pkg/ccl/logictestccl/testdata/logic_test/partitioning_hash_sharded_index b/pkg/ccl/logictestccl/testdata/logic_test/partitioning_hash_sharded_index index 987f86f88d2b..881aa7337ec2 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/partitioning_hash_sharded_index +++ b/pkg/ccl/logictestccl/testdata/logic_test/partitioning_hash_sharded_index @@ -102,7 +102,7 @@ CREATE TABLE t_to_be_hashed ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( a INT8 NOT NULL, @@ -120,7 +120,7 @@ statement ok CREATE INDEX ON t_to_be_hashed (c) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( a INT8 NOT NULL, @@ -140,7 +140,7 @@ statement ok CREATE UNIQUE INDEX ON t_to_be_hashed (c) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( a INT8 NOT NULL, @@ -161,7 +161,7 @@ statement ok ALTER TABLE t_to_be_hashed ALTER PRIMARY KEY USING COLUMNS (a) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( a INT8 NOT NULL, @@ -192,7 +192,7 @@ CREATE TABLE t_idx_pk_hashed_1 ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_idx_pk_hashed_1]; +SELECT create_statement FROM [SHOW CREATE TABLE t_idx_pk_hashed_1]; ---- CREATE TABLE public.t_idx_pk_hashed_1 ( crdb_internal_a_shard_16 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 16:::INT8)) VIRTUAL, @@ -223,7 +223,7 @@ CREATE TABLE t_idx_pk_hashed_2 ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_idx_pk_hashed_2]; +SELECT create_statement FROM [SHOW CREATE TABLE t_idx_pk_hashed_2]; ---- CREATE TABLE public.t_idx_pk_hashed_2 ( a INT8 NOT NULL, diff --git a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_hash_sharded_index b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_hash_sharded_index index ca4a8a026c9f..f59056b5b821 100644 --- a/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_hash_sharded_index +++ b/pkg/ccl/logictestccl/testdata/logic_test/regional_by_row_hash_sharded_index @@ -44,7 +44,7 @@ CREATE TABLE t_to_be_hashed ( ) LOCALITY REGIONAL BY ROW; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( pk INT8 NOT NULL, @@ -58,7 +58,7 @@ statement ok CREATE INDEX ON t_to_be_hashed (b) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( pk INT8 NOT NULL, @@ -74,7 +74,7 @@ statement ok CREATE UNIQUE INDEX ON t_to_be_hashed (b) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( pk INT8 NOT NULL, @@ -91,7 +91,7 @@ statement ok ALTER TABLE t_to_be_hashed ALTER PRIMARY KEY USING COLUMNS (pk) USING HASH; query T -SELECT @2 FROM [SHOW CREATE TABLE t_to_be_hashed]; +SELECT create_statement FROM [SHOW CREATE TABLE t_to_be_hashed]; ---- CREATE TABLE public.t_to_be_hashed ( pk INT8 NOT NULL, @@ -114,7 +114,7 @@ CREATE TABLE t_regional_pk_hashed_1 ( ) LOCALITY REGIONAL BY ROW; query T -SELECT @2 FROM [SHOW CREATE TABLE t_regional_pk_hashed_1]; +SELECT create_statement FROM [SHOW CREATE TABLE t_regional_pk_hashed_1]; ---- CREATE TABLE public.t_regional_pk_hashed_1 ( crdb_internal_pk_shard_16 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(pk)), 16:::INT8)) VIRTUAL, @@ -137,7 +137,7 @@ CREATE TABLE t_regional_pk_hashed_2 ( ) LOCALITY REGIONAL BY ROW; query T -SELECT @2 FROM [SHOW CREATE TABLE t_regional_pk_hashed_2]; +SELECT create_statement FROM [SHOW CREATE TABLE t_regional_pk_hashed_2]; ---- CREATE TABLE public.t_regional_pk_hashed_2 ( pk INT8 NOT NULL, diff --git a/pkg/cli/clisqlshell/sql_test.go b/pkg/cli/clisqlshell/sql_test.go index 9601ddf7292f..eb36d945e3f3 100644 --- a/pkg/cli/clisqlshell/sql_test.go +++ b/pkg/cli/clisqlshell/sql_test.go @@ -57,7 +57,7 @@ func Example_sql() { // growing capacity starting at 1 (the batch sizes will be 1, 2, 4, ...), // and with the query below the division by zero error will occur after the // first batch consisting of 1 row has been returned to the client. - c.RunWithArgs([]string{`sql`, `-e`, `select 1/(@1-2) from generate_series(1,3)`}) + c.RunWithArgs([]string{`sql`, `-e`, `select 1/(i-2) from generate_series(1,3) g(i)`}) c.RunWithArgs([]string{`sql`, `-e`, `SELECT '20:01:02+03:04:05'::timetz AS regression_65066`}) c.RunWithArgs([]string{`sql`, `-e`, `CREATE USER my_user WITH CREATEDB; GRANT admin TO my_user;`}) c.RunWithArgs([]string{`sql`, `-e`, `\du my_user`}) @@ -116,7 +116,7 @@ func Example_sql() { // CREATE TABLE // x // sql -e copy t.f from stdin - // sql -e select 1/(@1-2) from generate_series(1,3) + // sql -e select 1/(i-2) from generate_series(1,3) g(i) // ?column? // -1.0000000000000000000 // (error encountered after some results were delivered) diff --git a/pkg/cli/interactive_tests/test_notice.tcl b/pkg/cli/interactive_tests/test_notice.tcl index fbb7e8f47b14..cc57a97bdd7c 100644 --- a/pkg/cli/interactive_tests/test_notice.tcl +++ b/pkg/cli/interactive_tests/test_notice.tcl @@ -8,7 +8,7 @@ spawn $argv demo --no-line-editor --no-example-database eexpect root@ start_test "Test that notices always appear at the end after all results." -send "SELECT IF(@1=4,crdb_internal.notice('hello'),@1) AS MYRES FROM generate_series(1,10);\r" +send "SELECT IF(i=4,crdb_internal.notice('hello'),i) AS MYRES FROM generate_series(1,10) g(i);\r" eexpect myres eexpect 1 eexpect 10 diff --git a/pkg/cli/interactive_tests/test_url_db_override.tcl b/pkg/cli/interactive_tests/test_url_db_override.tcl index 407cac6e3fd0..16620cac725f 100644 --- a/pkg/cli/interactive_tests/test_url_db_override.tcl +++ b/pkg/cli/interactive_tests/test_url_db_override.tcl @@ -50,12 +50,12 @@ end_test start_test "Check that the database flag overrides the db if URL is already set." -spawn $argv sql --url "postgresql://root@localhost:26257/system?sslmode=disable" -e "select length(@1) as l, @1 as db from \[show database\]" --format=csv +spawn $argv sql --url "postgresql://root@localhost:26257/system?sslmode=disable" -e "select length(database) as l, database as db from \[show database\]" --format=csv eexpect "l,db" eexpect "6,system" eexpect eof -spawn $argv sql --url "postgresql://root@localhost:26257/system?sslmode=disable" --database test -e "select length(@1) as l, @1 as db from \[show database\]" --format=csv +spawn $argv sql --url "postgresql://root@localhost:26257/system?sslmode=disable" --database test -e "select length(database) as l, database as db from \[show database\]" --format=csv eexpect "l,db" eexpect "4,test" eexpect eof @@ -63,12 +63,12 @@ end_test start_test "Check that the database flag does override the database if none was present in the URL." # Use empty path. -spawn $argv sql --url "postgresql://root@localhost:26257?sslmode=disable" --database system -e "select length(@1) as l, @1 as db from \[show database\]" --format=csv +spawn $argv sql --url "postgresql://root@localhost:26257?sslmode=disable" --database system -e "select length(database) as l, database as db from \[show database\]" --format=csv eexpect "l,db" eexpect "6,system" eexpect eof # Use path = / -spawn $argv sql --url "postgresql://root@localhost:26257/?sslmode=disable" --database system -e "select length(@1) as l, @1 as db from \[show database\]" --format=csv +spawn $argv sql --url "postgresql://root@localhost:26257/?sslmode=disable" --database system -e "select length(database) as l, database as db from \[show database\]" --format=csv eexpect "l,db" eexpect "6,system" eexpect eof @@ -84,12 +84,12 @@ end_test set ::env(COCKROACH_INSECURE) "false" start_test "Check that the user flag override the user if URL is already set." -spawn $argv sql --url "postgresql://test@localhost:26257?sslmode=disable" -e "select length(@1) as l, @1 as u from \[show session_user\]" --format=csv +spawn $argv sql --url "postgresql://test@localhost:26257?sslmode=disable" -e "select length(session_user) as l, session_user as u from \[show session_user\]" --format=csv eexpect "l,u" eexpect "4,test" eexpect eof -spawn $argv sql --url "postgresql://root@localhost:26257?sslmode=disable" --user test -e "select length(@1) as l, @1 as u from \[show session_user\]" --format=csv +spawn $argv sql --url "postgresql://root@localhost:26257?sslmode=disable" --user test -e "select length(session_user) as l, session_user as u from \[show session_user\]" --format=csv eexpect "l,u" eexpect "4,test" eexpect eof diff --git a/pkg/sql/delegate/show_syntax.go b/pkg/sql/delegate/show_syntax.go index fccfaf95ae94..3c44df53e88f 100644 --- a/pkg/sql/delegate/show_syntax.go +++ b/pkg/sql/delegate/show_syntax.go @@ -27,17 +27,17 @@ import ( func (d *delegator) delegateShowSyntax(n *tree.ShowSyntax) (tree.Statement, error) { // Construct an equivalent SELECT query that produces the results: // - // SELECT @1 AS field, @2 AS message + // SELECT f AS field, m AS message // FROM (VALUES // ('file', 'foo.go'), // ('line', '123'), // ('function', 'blix()'), // ('detail', 'some details'), - // ('hint', 'some hints')) + // ('hint', 'some hints')) v(f, m) // var query bytes.Buffer fmt.Fprintf( - &query, "SELECT @1 AS %s, @2 AS %s FROM (VALUES ", + &query, "SELECT f AS %s, m AS %s FROM (VALUES ", colinfo.ShowSyntaxColumns[0].Name, colinfo.ShowSyntaxColumns[1].Name, ) @@ -64,7 +64,7 @@ func (d *delegator) delegateShowSyntax(n *tree.ShowSyntax) (tree.Statement, erro }, nil, /* reportErr */ ) - query.WriteByte(')') + query.WriteString(") v(f, m)") return parse(query.String()) } diff --git a/pkg/sql/exec_util.go b/pkg/sql/exec_util.go index d2fb23787a26..1ebe7cf930c3 100644 --- a/pkg/sql/exec_util.go +++ b/pkg/sql/exec_util.go @@ -3381,6 +3381,10 @@ func (m *sessionDataMutator) SetExperimentalHashGroupJoinEnabled(val bool) { m.data.ExperimentalHashGroupJoinEnabled = val } +func (m *sessionDataMutator) SetAllowOrdinalColumnReference(val bool) { + m.data.AllowOrdinalColumnReferences = val +} + // Utility functions related to scrubbing sensitive information on SQL Stats. // quantizeCounts ensures that the Count field in the diff --git a/pkg/sql/logictest/testdata/logic_test/alter_primary_key b/pkg/sql/logictest/testdata/logic_test/alter_primary_key index d7786a23067d..e41b527caa58 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_primary_key +++ b/pkg/sql/logictest/testdata/logic_test/alter_primary_key @@ -1394,7 +1394,7 @@ statement ok ALTER TABLE t ALTER PRIMARY KEY USING COLUMNS (k); query T -SELECT @2 FROM [SHOW CREATE TABLE t]; +SELECT create_statement FROM [SHOW CREATE TABLE t]; ---- CREATE TABLE public.t ( a INT8 NOT NULL, @@ -1430,7 +1430,7 @@ statement ok ALTER TABLE t ALTER PRIMARY KEY USING COLUMNS (b, k); query T -SELECT @2 FROM [SHOW CREATE TABLE t]; +SELECT create_statement FROM [SHOW CREATE TABLE t]; ---- CREATE TABLE public.t ( a INT8 NOT NULL, @@ -1474,7 +1474,7 @@ statement ok ALTER TABLE t ALTER PRIMARY KEY USING COLUMNS (a); query T -SELECT @2 FROM [SHOW CREATE TABLE t]; +SELECT create_statement FROM [SHOW CREATE TABLE t]; ---- CREATE TABLE public.t ( a INT8 NOT NULL, @@ -1548,7 +1548,7 @@ statement ok ALTER TABLE t_test_param ALTER PRIMARY KEY USING COLUMNS (b) USING HASH WITH BUCKET_COUNT = 5; query T -SELECT @2 FROM [SHOW CREATE TABLE t_test_param] +SELECT create_statement FROM [SHOW CREATE TABLE t_test_param] ---- CREATE TABLE public.t_test_param ( a INT8 NOT NULL, @@ -1578,7 +1578,7 @@ COMMENT ON CONSTRAINT i2 ON pkey_comment IS 'idx3'; # Comment should exist inside the create statement, so filter it out query T -SELECT substring(@2, strpos(@2, 'COMMENT')) FROM [SHOW CREATE pkey_comment]; +SELECT substring(create_statement, strpos(create_statement, 'COMMENT')) FROM [SHOW CREATE pkey_comment]; ---- COMMENT ON INDEX public.pkey_comment@pkey IS 'idx'; COMMENT ON INDEX public.pkey_comment@i2 IS 'idx2'; @@ -1592,7 +1592,7 @@ ALTER TABLE pkey_comment ALTER PRIMARY KEY USING COLUMNS (b); # No comment exists inside the CREATE statement skipif config local-legacy-schema-changer query T -SELECT substring(@2, strpos(@2, 'COMMENT')) FROM [SHOW CREATE pkey_comment]; +SELECT substring(create_statement, strpos(create_statement, 'COMMENT')) FROM [SHOW CREATE pkey_comment]; ---- COMMENT ON INDEX public.pkey_comment@pkey IS 'idx'; COMMENT ON INDEX public.pkey_comment@i2 IS 'idx2'; diff --git a/pkg/sql/logictest/testdata/logic_test/array b/pkg/sql/logictest/testdata/logic_test/array index b03eddb5b838..fd359dad0784 100644 --- a/pkg/sql/logictest/testdata/logic_test/array +++ b/pkg/sql/logictest/testdata/logic_test/array @@ -333,7 +333,7 @@ a # From a column ordinal. query T -SELECT @1[1] FROM (SELECT ARRAY['a','b','c'] AS a) +SELECT a[1] FROM (SELECT ARRAY['a','b','c'] AS a) ---- a diff --git a/pkg/sql/logictest/testdata/logic_test/create_index b/pkg/sql/logictest/testdata/logic_test/create_index index f9987f3c44a8..a274bb8e8bbd 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_index +++ b/pkg/sql/logictest/testdata/logic_test/create_index @@ -387,7 +387,7 @@ statement ok CREATE UNIQUE INDEX idx_t_hash_b ON t_hash (b) USING HASH WITH BUCKET_COUNT = 5; query T -SELECT @2 FROM [SHOW CREATE TABLE t_hash] +SELECT create_statement FROM [SHOW CREATE TABLE t_hash] ---- CREATE TABLE public.t_hash ( pk INT8 NOT NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/create_table b/pkg/sql/logictest/testdata/logic_test/create_table index 7d3f6a996b9a..b60baf51abb2 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_table +++ b/pkg/sql/logictest/testdata/logic_test/create_table @@ -847,7 +847,7 @@ CREATE TABLE t_good_hash_indexes_1 ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_good_hash_indexes_1]; +SELECT create_statement FROM [SHOW CREATE TABLE t_good_hash_indexes_1]; ---- CREATE TABLE public.t_good_hash_indexes_1 ( crdb_internal_a_shard_5 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 5:::INT8)) VIRTUAL, @@ -866,7 +866,7 @@ CREATE TABLE t_good_hash_indexes_2 ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_good_hash_indexes_2]; +SELECT create_statement FROM [SHOW CREATE TABLE t_good_hash_indexes_2]; ---- CREATE TABLE public.t_good_hash_indexes_2 ( a INT8 NOT NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/hash_sharded_index b/pkg/sql/logictest/testdata/logic_test/hash_sharded_index index 8180ad6a35b4..2f1fb018f623 100644 --- a/pkg/sql/logictest/testdata/logic_test/hash_sharded_index +++ b/pkg/sql/logictest/testdata/logic_test/hash_sharded_index @@ -1,5 +1,5 @@ # Tests for creating a hash sharded primary key -statement ok +statement ok CREATE TABLE sharded_primary (a INT PRIMARY KEY USING HASH WITH (bucket_count=10)) query TT @@ -769,7 +769,7 @@ statement ok $create_statement query T -SELECT @2 FROM [SHOW CREATE TABLE t] +SELECT create_statement FROM [SHOW CREATE TABLE t] ---- CREATE TABLE public.t ( crdb_internal_a_shard_8 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 8:::INT8)) VIRTUAL, @@ -792,7 +792,7 @@ CREATE TABLE public.t ( ) query T -SELECT @2 FROM [SHOW CREATE TABLE t] +SELECT create_statement FROM [SHOW CREATE TABLE t] ---- CREATE TABLE public.t ( crdb_internal_a_shard_8 INT4 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 8:::INT8)) VIRTUAL, @@ -856,7 +856,7 @@ CREATE TABLE t_default_bucket_16 ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE t_default_bucket_16] +SELECT create_statement FROM [SHOW CREATE TABLE t_default_bucket_16] ---- CREATE TABLE public.t_default_bucket_16 ( crdb_internal_a_shard_16 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 16:::INT8)) VIRTUAL, @@ -879,7 +879,7 @@ statement ok CREATE TABLE t_default_bucket_8 (a INT PRIMARY KEY USING HASH); query T -SELECT @2 FROM [SHOW CREATE TABLE t_default_bucket_8] +SELECT create_statement FROM [SHOW CREATE TABLE t_default_bucket_8] ---- CREATE TABLE public.t_default_bucket_8 ( crdb_internal_a_shard_8 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 8:::INT8)) VIRTUAL, diff --git a/pkg/sql/logictest/testdata/logic_test/information_schema b/pkg/sql/logictest/testdata/logic_test/information_schema index 17c643d6135b..32a97a3cd323 100644 --- a/pkg/sql/logictest/testdata/logic_test/information_schema +++ b/pkg/sql/logictest/testdata/logic_test/information_schema @@ -4739,6 +4739,7 @@ WHERE ); ---- variable value +allow_ordinal_column_references off allow_prepare_as_opt_plan off alter_primary_region_super_region_override off application_name · diff --git a/pkg/sql/logictest/testdata/logic_test/inverted_index b/pkg/sql/logictest/testdata/logic_test/inverted_index index 7685a5e324fa..632efa58c849 100644 --- a/pkg/sql/logictest/testdata/logic_test/inverted_index +++ b/pkg/sql/logictest/testdata/logic_test/inverted_index @@ -1589,7 +1589,7 @@ CREATE TABLE table_desc_inverted_index ( ); query T -SELECT @2 FROM [SHOW CREATE TABLE table_desc_inverted_index]; +SELECT create_statement FROM [SHOW CREATE TABLE table_desc_inverted_index]; ---- CREATE TABLE public.table_desc_inverted_index ( id INT8 NOT NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/name_escapes b/pkg/sql/logictest/testdata/logic_test/name_escapes index bd086c16a935..dd159d2c9eac 100644 --- a/pkg/sql/logictest/testdata/logic_test/name_escapes +++ b/pkg/sql/logictest/testdata/logic_test/name_escapes @@ -41,20 +41,19 @@ SHOW CREATE TABLE ";--notbetter" # Check that view creates handle strange things properly. statement ok -CREATE VIEW ";--alsoconcerning" AS SELECT @1 AS a, @2 AS b, @3 AS c FROM ";--notbetter" +CREATE VIEW ";--alsoconcerning" AS SELECT x AS a, y AS b FROM ";--notbetter" query TT SHOW CREATE VIEW ";--alsoconcerning" ---- ";--alsoconcerning" CREATE VIEW public.";--alsoconcerning" ( a, - b, - c - ) AS SELECT @1 AS a, @2 AS b, @3 AS c FROM test.public.";--notbetter" + b + ) AS SELECT x AS a, y AS b FROM test.public.";--notbetter" # Check that "create table as" handles strange things properly. statement ok -CREATE TABLE ";--dontask" AS SELECT @1 AS a, @2 AS b, @3 AS c FROM ";--notbetter" +CREATE TABLE ";--dontask" AS SELECT x AS a, y AS b FROM ";--notbetter" query TT SHOW CREATE TABLE ";--dontask" @@ -62,7 +61,6 @@ SHOW CREATE TABLE ";--dontask" ";--dontask" CREATE TABLE public.";--dontask" ( a INT8 NULL, b INT8 NULL, - c INT8 NULL, rowid INT8 NOT VISIBLE NOT NULL DEFAULT unique_rowid(), CONSTRAINT ";--dontask_pkey" PRIMARY KEY (rowid ASC) ) diff --git a/pkg/sql/logictest/testdata/logic_test/numeric_references b/pkg/sql/logictest/testdata/logic_test/numeric_references index fd724597b03a..6216330492b1 100644 --- a/pkg/sql/logictest/testdata/logic_test/numeric_references +++ b/pkg/sql/logictest/testdata/logic_test/numeric_references @@ -144,7 +144,7 @@ SELECT * FROM [$num_ref_id as num_ref_alias] 5 NULL NULL statement OK -DELETE FROM [$num_ref_id AS num_ref_alias]@bc WHERE @1=5 +DELETE FROM [$num_ref_id AS num_ref_alias]@bc WHERE p=5 query I DELETE FROM [$num_ref_id AS num_ref_alias] WHERE d=40 RETURNING num_ref_alias.c diff --git a/pkg/sql/logictest/testdata/logic_test/order_by b/pkg/sql/logictest/testdata/logic_test/order_by index 2fb8de764275..23ebd8c9c86e 100644 --- a/pkg/sql/logictest/testdata/logic_test/order_by +++ b/pkg/sql/logictest/testdata/logic_test/order_by @@ -348,7 +348,7 @@ SELECT * FROM kv AS a, kv AS b ORDER BY PRIMARY KEY kv # is a real table, not an alias. # statement error no data source matches prefix: test.public.kv -SELECT k FROM (SELECT @1, @1 FROM generate_series(1,10)) AS kv(k,v) ORDER BY PRIMARY KEY kv +SELECT k FROM (SELECT i, i FROM generate_series(1,10) g(i)) AS kv(k,v) ORDER BY PRIMARY KEY kv statement error no data source matches prefix: test.public.kv CREATE TABLE unrelated(x INT); SELECT * FROM unrelated ORDER BY PRIMARY KEY kv diff --git a/pkg/sql/logictest/testdata/logic_test/ordinal_references b/pkg/sql/logictest/testdata/logic_test/ordinal_references index 66f9891df310..72b1c301893b 100644 --- a/pkg/sql/logictest/testdata/logic_test/ordinal_references +++ b/pkg/sql/logictest/testdata/logic_test/ordinal_references @@ -1,3 +1,6 @@ +statement ok +SET allow_ordinal_column_references=true + statement ok CREATE TABLE foo(a INT, b CHAR) diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 832d272cf09e..9a878fb16257 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -2761,6 +2761,7 @@ WHERE name NOT IN ('optimizer', 'crdb_version', 'session_id', 'distsql_workmem', 'copy_fast_path_enabled') ---- name setting category short_desc extra_desc vartype +allow_ordinal_column_references off NULL NULL NULL string alter_primary_region_super_region_override off NULL NULL NULL string application_name · NULL NULL NULL string avoid_buffering off NULL NULL NULL string @@ -2900,6 +2901,7 @@ WHERE name NOT IN ('optimizer', 'crdb_version', 'session_id', 'distsql_workmem', 'copy_fast_path_enabled') ---- name setting unit context enumvals boot_val reset_val +allow_ordinal_column_references off NULL user NULL off off alter_primary_region_super_region_override off NULL user NULL off off application_name · NULL user NULL · · avoid_buffering off NULL user NULL false false @@ -3033,6 +3035,7 @@ query TTTTTT colnames SELECT name, source, min_val, max_val, sourcefile, sourceline FROM pg_catalog.pg_settings ---- name source min_val max_val sourcefile sourceline +allow_ordinal_column_references NULL NULL NULL NULL NULL alter_primary_region_super_region_override NULL NULL NULL NULL NULL application_name NULL NULL NULL NULL NULL avoid_buffering NULL NULL NULL NULL NULL diff --git a/pkg/sql/logictest/testdata/logic_test/show_create b/pkg/sql/logictest/testdata/logic_test/show_create index 5f96cb968dd1..00febc1e4950 100644 --- a/pkg/sql/logictest/testdata/logic_test/show_create +++ b/pkg/sql/logictest/testdata/logic_test/show_create @@ -119,7 +119,7 @@ statement ok COMMENT ON COLUMN t.c IS 'first comment'; query T -SELECT @2 FROM [SHOW CREATE TABLE t]; +SELECT create_statement FROM [SHOW CREATE TABLE t]; ---- CREATE TABLE public.t ( c INT8 NULL, @@ -132,7 +132,7 @@ statement ok ALTER TABLE t ALTER COLUMN c TYPE character varying; query T -SELECT @2 FROM [SHOW CREATE TABLE t]; +SELECT create_statement FROM [SHOW CREATE TABLE t]; ---- CREATE TABLE public.t ( c VARCHAR NULL, diff --git a/pkg/sql/logictest/testdata/logic_test/show_source b/pkg/sql/logictest/testdata/logic_test/show_source index 95a4db7c1a1a..07757fb88f0f 100644 --- a/pkg/sql/logictest/testdata/logic_test/show_source +++ b/pkg/sql/logictest/testdata/logic_test/show_source @@ -26,6 +26,7 @@ FROM [SHOW ALL] WHERE variable NOT IN ('optimizer', 'crdb_version', 'session_id', 'distsql_workmem', 'copy_fast_path_enabled') ---- variable value +allow_ordinal_column_references off alter_primary_region_super_region_override off application_name · avoid_buffering off diff --git a/pkg/sql/logictest/testdata/logic_test/statement_source b/pkg/sql/logictest/testdata/logic_test/statement_source index 8f624f8a8877..5f07c7a6925b 100644 --- a/pkg/sql/logictest/testdata/logic_test/statement_source +++ b/pkg/sql/logictest/testdata/logic_test/statement_source @@ -8,7 +8,7 @@ query error statement source "DELETE FROM a" does not return any columns SELECT 1 FROM [DELETE FROM a] query II -SELECT @1, a+b FROM [INSERT INTO a VALUES (1,2) RETURNING b,a] +SELECT b, a+b FROM [INSERT INTO a VALUES (1,2) RETURNING b,a] ---- 2 3 diff --git a/pkg/sql/logictest/testdata/logic_test/udf b/pkg/sql/logictest/testdata/logic_test/udf index 0fb81a87f484..64c955dba195 100644 --- a/pkg/sql/logictest/testdata/logic_test/udf +++ b/pkg/sql/logictest/testdata/logic_test/udf @@ -95,7 +95,7 @@ statement ok CREATE FUNCTION f_no_ref(a int) RETURNS INT IMMUTABLE AS 'SELECT 1' LANGUAGE SQL query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_no_ref]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_no_ref]; ---- CREATE FUNCTION public.f_no_ref(IN a INT8) RETURNS INT8 @@ -133,7 +133,7 @@ SELECT nextval('sq1'); $$ query T -SELECT @2 FROM [SHOW CREATE FUNCTION f]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f]; ---- CREATE FUNCTION public.f(IN a test.public.notmyworkday) RETURNS INT8 @@ -273,7 +273,7 @@ $$ 122 test_cross_db 123 public 124 f_cross_db subtest show_create_function query T -SELECT @2 FROM [SHOW CREATE FUNCTION proc_f]; +SELECT create_statement FROM [SHOW CREATE FUNCTION proc_f]; ---- CREATE FUNCTION public.proc_f(IN INT8) RETURNS INT8 @@ -298,7 +298,7 @@ statement error pq: unknown function: proc_f_2() SHOW CREATE FUNCTION proc_f_2; query T -SELECT @2 FROM [SHOW CREATE FUNCTION sc.proc_f_2]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc.proc_f_2]; ---- CREATE FUNCTION sc.proc_f_2(IN STRING) RETURNS STRING @@ -314,7 +314,7 @@ statement ok SET search_path = sc; query T -SELECT @2 FROM [SHOW CREATE FUNCTION proc_f_2]; +SELECT create_statement FROM [SHOW CREATE FUNCTION proc_f_2]; ---- CREATE FUNCTION sc.proc_f_2(IN STRING) RETURNS STRING @@ -385,7 +385,7 @@ statement ok SET search_path = public,sc1 query T -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_drop]; ---- CREATE FUNCTION public.f_test_drop() RETURNS INT8 @@ -407,7 +407,7 @@ CREATE FUNCTION public.f_test_drop(IN INT8) $$ query T -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; ---- CREATE FUNCTION sc1.f_test_drop(IN INT8) RETURNS INT8 @@ -442,7 +442,7 @@ statement ok DROP FUNCTION f_test_drop(); query T -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_drop]; ---- CREATE FUNCTION public.f_test_drop(IN INT8) RETURNS INT8 @@ -455,7 +455,7 @@ CREATE FUNCTION public.f_test_drop(IN INT8) $$ query T -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; ---- CREATE FUNCTION sc1.f_test_drop(IN INT8) RETURNS INT8 @@ -473,10 +473,10 @@ statement ok DROP FUNCTION f_test_drop(INT), f_test_drop(INT); statement error pq: unknown function: public.f_test_drop\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_drop]; query T -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; ---- CREATE FUNCTION sc1.f_test_drop(IN INT8) RETURNS INT8 @@ -492,7 +492,7 @@ statement ok DROP FUNCTION f_test_drop(INT); statement error pq: unknown function: sc1.f_test_drop\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; # If there are identical function signatures in different schemas, multiple drop # statements should drop them all. This matches postgres behavior. @@ -501,7 +501,7 @@ CREATE FUNCTION public.f_test_drop() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; CREATE FUNCTION sc1.f_test_drop() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_drop]; ---- CREATE FUNCTION public.f_test_drop() RETURNS INT8 @@ -514,7 +514,7 @@ CREATE FUNCTION public.f_test_drop() $$ query T -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; ---- CREATE FUNCTION sc1.f_test_drop() RETURNS INT8 @@ -533,10 +533,10 @@ DROP FUNCTION f_test_drop(); COMMIT; statement error pq: unknown function: public.f_test_drop\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_drop]; statement error pq: unknown function: sc1.f_test_drop\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; +SELECT create_statement FROM [SHOW CREATE FUNCTION sc1.f_test_drop]; statement ok SET search_path = public @@ -606,7 +606,7 @@ statement ok CREATE VIEW v AS SELECT lower('hello'); query T -SELECT @2 FROM [SHOW CREATE FUNCTION test_vf_f]; +SELECT create_statement FROM [SHOW CREATE FUNCTION test_vf_f]; ---- CREATE FUNCTION public.test_vf_f() RETURNS STRING @@ -1059,7 +1059,7 @@ statement ok CREATE FUNCTION f_test_alter_opt(INT) RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_opt]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_opt]; ---- CREATE FUNCTION public.f_test_alter_opt(IN INT8) RETURNS INT8 @@ -1081,7 +1081,7 @@ statement ok ALTER FUNCTION f_test_alter_opt IMMUTABLE LEAKPROOF STRICT; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_opt]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_opt]; ---- CREATE FUNCTION public.f_test_alter_opt(IN INT8) RETURNS INT8 @@ -1105,7 +1105,7 @@ statement ok CREATE FUNCTION f_test_alter_name_diff_in() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_name]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_name]; ---- CREATE FUNCTION public.f_test_alter_name(IN INT8) RETURNS INT8 @@ -1127,10 +1127,10 @@ statement ok ALTER FUNCTION f_test_alter_name RENAME TO f_test_alter_name_new statement error pq: unknown function: f_test_alter_name\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_name]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_name]; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_name_new]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_name_new]; ---- CREATE FUNCTION public.f_test_alter_name_new(IN INT8) RETURNS INT8 @@ -1146,10 +1146,10 @@ statement ok ALTER FUNCTION f_test_alter_name_new RENAME to f_test_alter_name_diff_in statement error pq: unknown function: f_test_alter_name_new\(\): function undefined -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_name_new]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_name_new]; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_alter_name_diff_in]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_alter_name_diff_in]; ---- CREATE FUNCTION public.f_test_alter_name_diff_in() RETURNS INT8 @@ -1319,7 +1319,7 @@ SELECT fn->>'id' AS id, fn->'parentSchemaId' 153 152 query T -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_sc]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_sc]; ---- CREATE FUNCTION public.f_test_sc() RETURNS INT8 @@ -1369,7 +1369,7 @@ SELECT fn->>'id' AS id, fn->'parentSchemaId' 153 152 query T -SELECT @2 FROM [SHOW CREATE FUNCTION public.f_test_sc]; +SELECT create_statement FROM [SHOW CREATE FUNCTION public.f_test_sc]; ---- CREATE FUNCTION public.f_test_sc() RETURNS INT8 @@ -1382,7 +1382,7 @@ CREATE FUNCTION public.f_test_sc() $$ query T -SELECT @2 FROM [SHOW CREATE FUNCTION test_alter_sc.f_test_sc]; +SELECT create_statement FROM [SHOW CREATE FUNCTION test_alter_sc.f_test_sc]; ---- CREATE FUNCTION test_alter_sc.f_test_sc() RETURNS INT8 @@ -1431,7 +1431,7 @@ statement error pq: cannot set leakproof on function with non-immutable volatili CREATE OR REPLACE FUNCTION f_test_cor(a INT, b INT) RETURNS INT LEAKPROOF LANGUAGE SQL AS $$ SELECT 1 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_cor]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_cor]; ---- CREATE FUNCTION public.f_test_cor(IN a INT8, IN b INT8) RETURNS INT8 @@ -1449,7 +1449,7 @@ statement ok CREATE OR REPLACE FUNCTION f_test_cor(a INT, b INT) RETURNS INT LANGUAGE SQL AS $$ SELECT 2 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_cor]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_cor]; ---- CREATE FUNCTION public.f_test_cor(IN a INT8, IN b INT8) RETURNS INT8 @@ -1465,7 +1465,7 @@ statement ok CREATE OR REPLACE FUNCTION f_test_cor(a INT, b INT) RETURNS INT IMMUTABLE LEAKPROOF STRICT LANGUAGE SQL AS $$ SELECT 3 $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_test_cor]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_test_cor]; ---- CREATE FUNCTION public.f_test_cor(IN a INT8, IN b INT8) RETURNS INT8 @@ -1508,7 +1508,7 @@ statement ok CREATE FUNCTION f_udt_rewrite() RETURNS notmyworkday LANGUAGE SQL AS $$ SELECT 'Monday':: notmyworkday $$; query T -SELECT @2 FROM [SHOW CREATE FUNCTION f_udt_rewrite]; +SELECT create_statement FROM [SHOW CREATE FUNCTION f_udt_rewrite]; ---- CREATE FUNCTION public.f_udt_rewrite() RETURNS test.public.notmyworkday diff --git a/pkg/sql/opt/exec/execbuilder/testdata/aggregate b/pkg/sql/opt/exec/execbuilder/testdata/aggregate index 43baa0ced1a7..eb74ca1b7630 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/aggregate +++ b/pkg/sql/opt/exec/execbuilder/testdata/aggregate @@ -1700,6 +1700,9 @@ vectorized: true statement ok CREATE TABLE foo(a INT, b CHAR) +statement ok +SET allow_ordinal_column_references=true + # Check that GROUP BY picks up column ordinals. query T EXPLAIN (VERBOSE) SELECT min(a) AS m FROM foo GROUP BY @1 @@ -1753,6 +1756,9 @@ vectorized: true table: foo@foo_pkey spans: FULL SCAN +statement ok +SET allow_ordinal_column_references=false + query T EXPLAIN (VERBOSE) SELECT array_agg(v) FROM (SELECT * FROM kv ORDER BY v) ---- diff --git a/pkg/sql/opt/exec/execbuilder/testdata/explain b/pkg/sql/opt/exec/execbuilder/testdata/explain index c182a746ac5e..96132bf9bfaf 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain @@ -640,7 +640,7 @@ ANALYZE system.role_options statement OK ANALYZE system.role_members -query T retry +query T retry EXPLAIN SHOW USERS ---- distribution: local @@ -709,14 +709,13 @@ vectorized: true estimated row count: 1 query T -EXPLAIN (VERBOSE) SELECT @1 FROM select_test +EXPLAIN (VERBOSE) SELECT last_value FROM select_test ---- distribution: local vectorized: true · -• render -│ columns: ("?column?") -│ render ?column?: last_value +• project +│ columns: (last_value) │ └── • sequence select columns: (last_value, log_cnt, is_called) diff --git a/pkg/sql/opt/exec/execbuilder/testdata/hash_sharded_index b/pkg/sql/opt/exec/execbuilder/testdata/hash_sharded_index index f4437e37543a..eb0e46afda4a 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/hash_sharded_index +++ b/pkg/sql/opt/exec/execbuilder/testdata/hash_sharded_index @@ -573,7 +573,7 @@ statement ok $create_statement query T -SELECT @2 FROM [SHOW CREATE TABLE t] +SELECT create_statement FROM [SHOW CREATE TABLE t] ---- CREATE TABLE public.t ( crdb_internal_a_shard_8 INT8 NOT VISIBLE NOT NULL AS (mod(fnv32(crdb_internal.datums_to_bytes(a)), 8:::INT8)) VIRTUAL, diff --git a/pkg/sql/opt/exec/execbuilder/testdata/orderby b/pkg/sql/opt/exec/execbuilder/testdata/orderby index f0759bc7640d..d76b8f3c9211 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/orderby +++ b/pkg/sql/opt/exec/execbuilder/testdata/orderby @@ -838,6 +838,9 @@ vectorized: true statement ok CREATE TABLE foo(a INT, b CHAR) +statement ok +SET allow_ordinal_column_references=true + # Check that sort by ordinal picks up the existing render. query T EXPLAIN (VERBOSE) SELECT b, a FROM foo ORDER BY @1 @@ -895,6 +898,9 @@ vectorized: true table: foo@foo_pkey spans: FULL SCAN +statement ok +SET allow_ordinal_column_references=false + # ------------------------------------------------------------------------------ # Check star expansion in ORDER BY. # ------------------------------------------------------------------------------ diff --git a/pkg/sql/opt/exec/execbuilder/testdata/spool b/pkg/sql/opt/exec/execbuilder/testdata/spool index f16a3bf2d325..83b3f07e0261 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/spool +++ b/pkg/sql/opt/exec/execbuilder/testdata/spool @@ -440,7 +440,7 @@ vectorized: true # Check that simple computations using RETURNING get their spool pulled up. query T -EXPLAIN SELECT * FROM [INSERT INTO t SELECT * FROM t2 RETURNING x+10] WHERE @1 < 3 LIMIT 10 +EXPLAIN SELECT * FROM [INSERT INTO t SELECT * FROM t2 RETURNING x+10 AS r] WHERE r < 3 LIMIT 10 ---- distribution: local vectorized: true @@ -451,14 +451,14 @@ vectorized: true │ │ count: 10 │ │ │ └── • filter -│ │ filter: "?column?" < 3 +│ │ filter: r < 3 │ │ │ └── • scan buffer │ label: buffer 1 │ └── • subquery │ id: @S1 - │ original sql: INSERT INTO t SELECT * FROM t2 RETURNING x + 10 + │ original sql: INSERT INTO t SELECT * FROM t2 RETURNING x + 10 AS r │ exec mode: all rows │ └── • buffer @@ -476,7 +476,7 @@ vectorized: true # Check that a pulled up spool gets elided at the top level. query T -EXPLAIN SELECT * FROM [INSERT INTO t SELECT * FROM t2 RETURNING x+10] WHERE @1 < 3 +EXPLAIN SELECT * FROM [INSERT INTO t SELECT * FROM t2 RETURNING x+10 AS r] WHERE r < 3 ---- distribution: local vectorized: true @@ -484,14 +484,14 @@ vectorized: true • root │ ├── • filter -│ │ filter: "?column?" < 3 +│ │ filter: r < 3 │ │ │ └── • scan buffer │ label: buffer 1 │ └── • subquery │ id: @S1 - │ original sql: INSERT INTO t SELECT * FROM t2 RETURNING x + 10 + │ original sql: INSERT INTO t SELECT * FROM t2 RETURNING x + 10 AS r │ exec mode: all rows │ └── • buffer diff --git a/pkg/sql/opt/memo/memo.go b/pkg/sql/opt/memo/memo.go index cf3665420c74..980b12ad4669 100644 --- a/pkg/sql/opt/memo/memo.go +++ b/pkg/sql/opt/memo/memo.go @@ -158,6 +158,7 @@ type Memo struct { testingOptimizerDisableRuleProbability float64 enforceHomeRegion bool variableInequalityLookupJoinEnabled bool + allowOrdinalColumnReferences bool // curRank is the highest currently in-use scalar expression rank. curRank opt.ScalarRank @@ -211,6 +212,7 @@ func (m *Memo) Init(ctx context.Context, evalCtx *eval.Context) { testingOptimizerDisableRuleProbability: evalCtx.SessionData().TestingOptimizerDisableRuleProbability, enforceHomeRegion: evalCtx.SessionData().EnforceHomeRegion, variableInequalityLookupJoinEnabled: evalCtx.SessionData().VariableInequalityLookupJoinEnabled, + allowOrdinalColumnReferences: evalCtx.SessionData().AllowOrdinalColumnReferences, } m.metadata.Init() m.logPropsBuilder.init(ctx, evalCtx, m) @@ -347,7 +349,8 @@ func (m *Memo) IsStale( m.testingOptimizerCostPerturbation != evalCtx.SessionData().TestingOptimizerCostPerturbation || m.testingOptimizerDisableRuleProbability != evalCtx.SessionData().TestingOptimizerDisableRuleProbability || m.enforceHomeRegion != evalCtx.SessionData().EnforceHomeRegion || - m.variableInequalityLookupJoinEnabled != evalCtx.SessionData().VariableInequalityLookupJoinEnabled { + m.variableInequalityLookupJoinEnabled != evalCtx.SessionData().VariableInequalityLookupJoinEnabled || + m.allowOrdinalColumnReferences != evalCtx.SessionData().AllowOrdinalColumnReferences { return true, nil } diff --git a/pkg/sql/opt/memo/memo_test.go b/pkg/sql/opt/memo/memo_test.go index 3b5cb8bf5b42..6763fcd48d3d 100644 --- a/pkg/sql/opt/memo/memo_test.go +++ b/pkg/sql/opt/memo/memo_test.go @@ -323,6 +323,12 @@ func TestMemoIsStale(t *testing.T) { evalCtx.SessionData().TestingOptimizerDisableRuleProbability = 0 notStale() + // Stale testing_optimizer_disable_rule_probability. + evalCtx.SessionData().AllowOrdinalColumnReferences = true + stale() + evalCtx.SessionData().AllowOrdinalColumnReferences = false + notStale() + // Stale data sources and schema. Create new catalog so that data sources are // recreated and can be modified independently. catalog = testcat.New() diff --git a/pkg/sql/opt/optbuilder/scalar.go b/pkg/sql/opt/optbuilder/scalar.go index 701a590a16dd..e1852fbf9dc4 100644 --- a/pkg/sql/opt/optbuilder/scalar.go +++ b/pkg/sql/opt/optbuilder/scalar.go @@ -352,6 +352,15 @@ func (b *Builder) buildScalar( out = b.factory.ConstructCase(input, whens, orElse) case *tree.IndexedVar: + // TODO(mgartner): Disallow ordinal column references completely in + // v23.2. + if !b.evalCtx.SessionData().AllowOrdinalColumnReferences { + panic(errors.WithHintf( + pgerror.Newf(pgcode.WarningDeprecatedFeature, "invalid syntax @%d", t.Idx+1), + "ordinal column references have been deprecated. "+ + "Use `SET allow_ordinal_column_references=true` to allow them", + )) + } if t.Idx < 0 || t.Idx >= len(inScope.cols) { panic(pgerror.Newf(pgcode.UndefinedColumn, "invalid column ordinal: @%d", t.Idx+1)) @@ -975,6 +984,7 @@ func (b *Builder) constructUnary( // TypedExprs can refer to columns in the current scope using IndexedVars (@1, // @2, etc). When we build a scalar, we have to provide information about these // columns. +// TODO(mgartner): Ordinal column references are deprecated. type ScalarBuilder struct { Builder scope scope diff --git a/pkg/sql/opt/optbuilder/testdata/orderby b/pkg/sql/opt/optbuilder/testdata/orderby index 29216a9b64d2..40e2e1f96d5b 100644 --- a/pkg/sql/opt/optbuilder/testdata/orderby +++ b/pkg/sql/opt/optbuilder/testdata/orderby @@ -596,6 +596,16 @@ sort build SELECT b, c FROM t ORDER BY @2 ---- +error (01P01): invalid syntax @2 + +build +SELECT b, c FROM t ORDER BY @4 +---- +error (01P01): invalid syntax @4 + +build set=allow_ordinal_column_references=true +SELECT b, c FROM t ORDER BY @2 +---- sort ├── columns: b:2 c:3 [hidden: column6:6] ├── ordering: +6 @@ -606,7 +616,7 @@ sort └── projections └── b:2 [as=column6:6] -build +build set=allow_ordinal_column_references=true SELECT b, c FROM t ORDER BY @4 ---- sort diff --git a/pkg/sql/opt/optbuilder/testdata/select b/pkg/sql/opt/optbuilder/testdata/select index 61ece45c3667..8a1b134d72b8 100644 --- a/pkg/sql/opt/optbuilder/testdata/select +++ b/pkg/sql/opt/optbuilder/testdata/select @@ -1029,6 +1029,11 @@ project build SELECT @1 AS r, @2 AS s FROM a ---- +error (01P01): invalid syntax @1 + +build set=allow_ordinal_column_references=true +SELECT @1 AS r, @2 AS s FROM a +---- project ├── columns: r:5!null s:6 ├── scan a diff --git a/pkg/sql/opt/optbuilder/testdata/sequence b/pkg/sql/opt/optbuilder/testdata/sequence index 8da99859eb21..ef9c74a808ae 100644 --- a/pkg/sql/opt/optbuilder/testdata/sequence +++ b/pkg/sql/opt/optbuilder/testdata/sequence @@ -101,6 +101,11 @@ sequence-select x build SELECT @1 FROM x ---- +error (01P01): invalid syntax @1 + +build set=allow_ordinal_column_references=true +SELECT @1 FROM x +---- project ├── columns: "?column?":4!null ├── sequence-select x diff --git a/pkg/sql/sessiondatapb/local_only_session_data.proto b/pkg/sql/sessiondatapb/local_only_session_data.proto index 44eb2ceb08ae..557db4716ac5 100644 --- a/pkg/sql/sessiondatapb/local_only_session_data.proto +++ b/pkg/sql/sessiondatapb/local_only_session_data.proto @@ -309,6 +309,9 @@ message LocalOnlySessionData { // single hash group-join operation. At the moment, there is no optimizer // support for this, so some things can be incorrect (e.g. EXPLAIN plans). bool experimental_hash_group_join_enabled = 84; + // AllowOrdinalColumnReferences indicates whether the deprecated ordinal + // column reference syntax (e.g., `SELECT @1 FROM t`) is allowed. + bool allow_ordinal_column_references = 85; /////////////////////////////////////////////////////////////////////////// // WARNING: consider whether a session parameter you're adding needs to // diff --git a/pkg/sql/vars.go b/pkg/sql/vars.go index 3f202eac3455..f7d4bd81877c 100644 --- a/pkg/sql/vars.go +++ b/pkg/sql/vars.go @@ -2370,6 +2370,21 @@ var varGen = map[string]sessionVar{ }, GlobalDefault: globalFalse, }, + `allow_ordinal_column_references`: { + GetStringVal: makePostgresBoolGetStringValFn(`allow_ordinal_column_references`), + Set: func(_ context.Context, m sessionDataMutator, s string) error { + b, err := paramparse.ParseBoolVar("allow_ordinal_column_references", s) + if err != nil { + return err + } + m.SetAllowOrdinalColumnReference(b) + return nil + }, + Get: func(evalCtx *extendedEvalContext, _ *kv.Txn) (string, error) { + return formatBoolAsPostgresSetting(evalCtx.SessionData().AllowOrdinalColumnReferences), nil + }, + GlobalDefault: globalFalse, + }, } // We want test coverage for this on and off so make it metamorphic.