diff --git a/pkg/ccl/importccl/import_stmt_test.go b/pkg/ccl/importccl/import_stmt_test.go index 61723c90dc09..0d7c9a753a37 100644 --- a/pkg/ccl/importccl/import_stmt_test.go +++ b/pkg/ccl/importccl/import_stmt_test.go @@ -469,7 +469,7 @@ COPY t (a, b, c) FROM stdin; // Verify the constraint is unvalidated. `SHOW CONSTRAINTS FROM weather - `: {{"weather", "weather_city_fkey", "FOREIGN KEY", "FOREIGN KEY (city) REFERENCES cities (city)", "false"}}, + `: {{"weather", "weather_city_fkey", "FOREIGN KEY", "FOREIGN KEY (city) REFERENCES cities(city)", "false"}}, }, }, { @@ -497,26 +497,26 @@ COPY t (a, b, c) FROM stdin; i INT8 NOT NULL, k INT8 NULL, CONSTRAINT a_pkey PRIMARY KEY (i ASC), - CONSTRAINT a_k_fkey FOREIGN KEY (k) REFERENCES a (i), + CONSTRAINT a_k_fkey FOREIGN KEY (k) REFERENCES a(i), INDEX a_auto_index_a_k_fkey (k ASC), - CONSTRAINT a_i_fkey FOREIGN KEY (i) REFERENCES b (j), + CONSTRAINT a_i_fkey FOREIGN KEY (i) REFERENCES b(j), FAMILY "primary" (i, k) )`}, { `CREATE TABLE b ( j INT8 NOT NULL, CONSTRAINT b_pkey PRIMARY KEY (j ASC), - CONSTRAINT b_j_fkey FOREIGN KEY (j) REFERENCES a (i), + CONSTRAINT b_j_fkey FOREIGN KEY (j) REFERENCES a(i), FAMILY "primary" (j) )`, }}, `SHOW CONSTRAINTS FROM a`: { - {"a", "a_i_fkey", "FOREIGN KEY", "FOREIGN KEY (i) REFERENCES b (j)", "false"}, - {"a", "a_k_fkey", "FOREIGN KEY", "FOREIGN KEY (k) REFERENCES a (i)", "false"}, + {"a", "a_i_fkey", "FOREIGN KEY", "FOREIGN KEY (i) REFERENCES b(j)", "false"}, + {"a", "a_k_fkey", "FOREIGN KEY", "FOREIGN KEY (k) REFERENCES a(i)", "false"}, {"a", "a_pkey", "PRIMARY KEY", "PRIMARY KEY (i ASC)", "true"}, }, `SHOW CONSTRAINTS FROM b`: { - {"b", "b_j_fkey", "FOREIGN KEY", "FOREIGN KEY (j) REFERENCES a (i)", "false"}, + {"b", "b_j_fkey", "FOREIGN KEY", "FOREIGN KEY (j) REFERENCES a(i)", "false"}, {"b", "b_pkey", "PRIMARY KEY", "PRIMARY KEY (j ASC)", "true"}, }, }, @@ -698,7 +698,7 @@ const ( temp_hi INT8 NULL, prcp FLOAT4 NULL, date DATE NULL, - CONSTRAINT weather_city_fkey FOREIGN KEY (city) REFERENCES cities (city), + CONSTRAINT weather_city_fkey FOREIGN KEY (city) REFERENCES cities(city), INDEX weather_auto_index_weather_city_fkey (city ASC), FAMILY "primary" (city, temp_lo, temp_hi, prcp, date, rowid) )` @@ -2385,7 +2385,7 @@ func TestImportCockroachDump(t *testing.T) { {"a", `CREATE TABLE a ( i INT8 NOT NULL, CONSTRAINT "primary" PRIMARY KEY (i ASC), - CONSTRAINT fk_i_ref_t FOREIGN KEY (i) REFERENCES t (i), + CONSTRAINT fk_i_ref_t FOREIGN KEY (i) REFERENCES t(i), FAMILY "primary" (i) )`}, }) diff --git a/pkg/cli/testdata/dump/reference_cycle b/pkg/cli/testdata/dump/reference_cycle index d4c286eb0d10..081e3209edb7 100644 --- a/pkg/cli/testdata/dump/reference_cycle +++ b/pkg/cli/testdata/dump/reference_cycle @@ -56,8 +56,8 @@ INSERT INTO loop_a (id, b_id) VALUES (2, 1), (3, 2); -ALTER TABLE loop_b ADD CONSTRAINT fk_a_id_ref_loop_a FOREIGN KEY (a_id) REFERENCES loop_a (id) ON DELETE CASCADE; -ALTER TABLE loop_a ADD CONSTRAINT b_id_delete_constraint FOREIGN KEY (b_id) REFERENCES loop_b (id) ON DELETE CASCADE; +ALTER TABLE loop_b ADD CONSTRAINT fk_a_id_ref_loop_a FOREIGN KEY (a_id) REFERENCES loop_a(id) ON DELETE CASCADE; +ALTER TABLE loop_a ADD CONSTRAINT b_id_delete_constraint FOREIGN KEY (b_id) REFERENCES loop_b(id) ON DELETE CASCADE; -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE loop_b VALIDATE CONSTRAINT fk_a_id_ref_loop_a; @@ -84,8 +84,8 @@ CREATE TABLE loop_a ( FAMILY "primary" (id, b_id) ); -ALTER TABLE loop_b ADD CONSTRAINT fk_a_id_ref_loop_a FOREIGN KEY (a_id) REFERENCES loop_a (id) ON DELETE CASCADE; -ALTER TABLE loop_a ADD CONSTRAINT b_id_delete_constraint FOREIGN KEY (b_id) REFERENCES loop_b (id) ON DELETE CASCADE; +ALTER TABLE loop_b ADD CONSTRAINT fk_a_id_ref_loop_a FOREIGN KEY (a_id) REFERENCES loop_a(id) ON DELETE CASCADE; +ALTER TABLE loop_a ADD CONSTRAINT b_id_delete_constraint FOREIGN KEY (b_id) REFERENCES loop_b(id) ON DELETE CASCADE; -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE loop_b VALIDATE CONSTRAINT fk_a_id_ref_loop_a; diff --git a/pkg/cli/testdata/dump/reference_order b/pkg/cli/testdata/dump/reference_order index 06bb336d3f86..a5912504b8a8 100644 --- a/pkg/cli/testdata/dump/reference_order +++ b/pkg/cli/testdata/dump/reference_order @@ -119,11 +119,11 @@ INSERT INTO s_tbl (id, v) VALUES (1, 10), (2, 11); -ALTER TABLE a ADD CONSTRAINT fk_i_ref_b FOREIGN KEY (i) REFERENCES b (i); -ALTER TABLE f ADD CONSTRAINT fk_g_ref_g FOREIGN KEY (g) REFERENCES g (i); -ALTER TABLE d ADD CONSTRAINT fk_e_ref_e FOREIGN KEY (e) REFERENCES e (i); -ALTER TABLE d ADD CONSTRAINT fk_f_ref_f FOREIGN KEY (f) REFERENCES f (i); -ALTER TABLE c ADD CONSTRAINT fk_i_ref_d FOREIGN KEY (i) REFERENCES d (i); +ALTER TABLE a ADD CONSTRAINT fk_i_ref_b FOREIGN KEY (i) REFERENCES b(i); +ALTER TABLE f ADD CONSTRAINT fk_g_ref_g FOREIGN KEY (g) REFERENCES g(i); +ALTER TABLE d ADD CONSTRAINT fk_e_ref_e FOREIGN KEY (e) REFERENCES e(i); +ALTER TABLE d ADD CONSTRAINT fk_f_ref_f FOREIGN KEY (f) REFERENCES f(i); +ALTER TABLE c ADD CONSTRAINT fk_i_ref_d FOREIGN KEY (i) REFERENCES d(i); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE a VALIDATE CONSTRAINT fk_i_ref_b; @@ -163,8 +163,8 @@ INSERT INTO e (i) VALUES INSERT INTO d (i, e, f) VALUES (1, 1, 1); -ALTER TABLE d ADD CONSTRAINT fk_e_ref_e FOREIGN KEY (e) REFERENCES e (i); -ALTER TABLE d ADD CONSTRAINT fk_f_ref_f FOREIGN KEY (f) REFERENCES f (i); +ALTER TABLE d ADD CONSTRAINT fk_e_ref_e FOREIGN KEY (e) REFERENCES e(i); +ALTER TABLE d ADD CONSTRAINT fk_f_ref_f FOREIGN KEY (f) REFERENCES f(i); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE d VALIDATE CONSTRAINT fk_e_ref_e; diff --git a/pkg/cli/testdata/dump/reference_self b/pkg/cli/testdata/dump/reference_self index 4e48731fb520..703454c0c55c 100644 --- a/pkg/cli/testdata/dump/reference_self +++ b/pkg/cli/testdata/dump/reference_self @@ -31,7 +31,7 @@ CREATE TABLE t ( INSERT INTO t (id, next_id) VALUES (1, NULL); -ALTER TABLE t ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY (next_id) REFERENCES t (id); +ALTER TABLE t ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY (next_id) REFERENCES t(id); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE t VALIDATE CONSTRAINT fk_next_id_ref_t; @@ -59,7 +59,7 @@ CREATE TABLE t ( INSERT INTO t (id, next_id) VALUES (1, 1); -ALTER TABLE t ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY (next_id) REFERENCES t (id); +ALTER TABLE t ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY (next_id) REFERENCES t(id); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE t VALIDATE CONSTRAINT fk_next_id_ref_t; @@ -88,7 +88,7 @@ CREATE TABLE "table" ( INSERT INTO "table" (id, "'") VALUES (1, 1); -ALTER TABLE "table" ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY ("'") REFERENCES "table" (id); +ALTER TABLE "table" ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY ("'") REFERENCES "table"(id); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE "table" VALIDATE CONSTRAINT fk_next_id_ref_t; @@ -108,7 +108,7 @@ CREATE TABLE "table" ( FAMILY "primary" (id, "'") ); -ALTER TABLE "table" ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY ("'") REFERENCES "table" (id); +ALTER TABLE "table" ADD CONSTRAINT fk_next_id_ref_t FOREIGN KEY ("'") REFERENCES "table"(id); -- Validate foreign key constraints. These can fail if there was unvalidated data during the dump. ALTER TABLE "table" VALIDATE CONSTRAINT fk_next_id_ref_t; diff --git a/pkg/sql/logictest/testdata/logic_test/alter_table b/pkg/sql/logictest/testdata/logic_test/alter_table index 2da71729e48f..0882ac357c88 100644 --- a/pkg/sql/logictest/testdata/logic_test/alter_table +++ b/pkg/sql/logictest/testdata/logic_test/alter_table @@ -90,11 +90,11 @@ a f b c query TTTTB colnames SHOW CONSTRAINTS FROM t ---- -table_name constraint_name constraint_type details validated -t check_a CHECK CHECK (a > 0) true -t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other (b) true -t foo UNIQUE UNIQUE (b ASC) true -t primary PRIMARY KEY PRIMARY KEY (a ASC) true +table_name constraint_name constraint_type details validated +t check_a CHECK CHECK ((a > 0)) true +t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other(b) true +t foo UNIQUE UNIQUE (b ASC) true +t primary PRIMARY KEY PRIMARY KEY (a ASC) true statement error CHECK INSERT INTO t (a, f) VALUES (-2, 9) @@ -120,10 +120,10 @@ INSERT INTO t (a) VALUES (-3) query TTTTB SHOW CONSTRAINTS FROM t ---- -t check_a CHECK CHECK (a > 0) true -t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other (b) true -t foo UNIQUE UNIQUE (b ASC) true -t primary PRIMARY KEY PRIMARY KEY (a ASC) true +t check_a CHECK CHECK ((a > 0)) true +t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other(b) true +t foo UNIQUE UNIQUE (b ASC) true +t primary PRIMARY KEY PRIMARY KEY (a ASC) true statement error duplicate constraint name ALTER TABLE t ADD CONSTRAINT check_a CHECK (a > 0) @@ -138,11 +138,11 @@ ALTER TABLE t ADD CHECK (a > 0) query TTTTB SHOW CONSTRAINTS FROM t ---- -t check_a CHECK CHECK (a > 0) true -t check_a1 CHECK CHECK (a > 0) true -t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other (b) true -t foo UNIQUE UNIQUE (b ASC) true -t primary PRIMARY KEY PRIMARY KEY (a ASC) true +t check_a CHECK CHECK ((a > 0)) true +t check_a1 CHECK CHECK ((a > 0)) true +t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other(b) true +t foo UNIQUE UNIQUE (b ASC) true +t primary PRIMARY KEY PRIMARY KEY (a ASC) true statement error constraint "typo" does not exist ALTER TABLE t VALIDATE CONSTRAINT typo @@ -160,11 +160,11 @@ ALTER TABLE t VALIDATE CONSTRAINT check_a query TTTTB SHOW CONSTRAINTS FROM t ---- -t check_a CHECK CHECK (a > 0) true -t check_a1 CHECK CHECK (a > 0) true -t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other (b) true -t foo UNIQUE UNIQUE (b ASC) true -t primary PRIMARY KEY PRIMARY KEY (a ASC) true +t check_a CHECK CHECK ((a > 0)) true +t check_a1 CHECK CHECK ((a > 0)) true +t fk_f_ref_other FOREIGN KEY FOREIGN KEY (f) REFERENCES other(b) true +t foo UNIQUE UNIQUE (b ASC) true +t primary PRIMARY KEY PRIMARY KEY (a ASC) true statement ok ALTER TABLE t DROP CONSTRAINT check_a, DROP CONSTRAINT check_a1 @@ -387,10 +387,10 @@ ALTER TABLE t ADD f INT UNIQUE REFERENCES other query TTTTB SHOW CONSTRAINTS FROM t ---- -t check_f CHECK CHECK (f > 1) true -t check_g CHECK CHECK (g > 0) true -t check_h CHECK CHECK (h > 0) true -t check_h1 CHECK CHECK (h < 10) true +t check_f CHECK CHECK ((f > 1)) true +t check_g CHECK CHECK ((g > 0)) true +t check_h CHECK CHECK ((h > 0)) true +t check_h1 CHECK CHECK ((h < 10)) true t primary PRIMARY KEY PRIMARY KEY (a ASC) true t t_h_key UNIQUE UNIQUE (h ASC) true @@ -425,8 +425,8 @@ ALTER TABLE t ADD COLUMN u INT UNIQUE, ADD COLUMN v INT UNIQUE, ADD CONSTRAINT c query TTTTB SHOW CONSTRAINTS FROM t ---- -t check_c_b CHECK CHECK (c > b) true -t ck CHECK CHECK (a > 0) true +t check_c_b CHECK CHECK ((c > b)) true +t ck CHECK CHECK ((a > 0)) true t primary PRIMARY KEY PRIMARY KEY (a ASC) true t t_d_key UNIQUE UNIQUE (d ASC) true t t_e_key UNIQUE UNIQUE (e ASC) true @@ -967,8 +967,8 @@ INSERT INTO t VALUES (NULL) query TTTTB SHOW CONSTRAINTS FROM t ---- -t a_auto_not_null CHECK CHECK (a IS NOT NULL) true -t a_auto_not_null1 CHECK CHECK (a IS NOT NULL) true +t a_auto_not_null CHECK CHECK ((a IS NOT NULL)) true +t a_auto_not_null1 CHECK CHECK ((a IS NOT NULL)) true statement ok DROP TABLE t diff --git a/pkg/sql/logictest/testdata/logic_test/builtin_function b/pkg/sql/logictest/testdata/logic_test/builtin_function index f6a0cc313fdf..c32e0d7e84f4 100644 --- a/pkg/sql/logictest/testdata/logic_test/builtin_function +++ b/pkg/sql/logictest/testdata/logic_test/builtin_function @@ -1782,7 +1782,7 @@ anyelement bit boolean bytea -character +bpchar date numeric double precision @@ -1979,8 +1979,8 @@ SELECT pg_catalog.pg_get_constraintdef(oid) FROM pg_catalog.pg_constraint WHERE conrelid='pg_constraintdef_test'::regclass ---- -FOREIGN KEY (a) REFERENCES pg_indexdef_test (a) ON DELETE CASCADE -CHECK (c > a) +FOREIGN KEY (a) REFERENCES pg_indexdef_test(a) ON DELETE CASCADE +CHECK ((c > a)) UNIQUE (b ASC) # These functions always return NULL since we don't support comments on vtable columns and databases. @@ -2213,3 +2213,9 @@ query B SELECT count(*) = 1 FROM crdb_internal.check_consistency(true, '\xff', '') ---- true + +# Sanity check pg_type_is_visible. +query BBB +SELECT pg_type_is_visible('int'::regtype), pg_type_is_visible(NULL), pg_type_is_visible(99999) +---- +true NULL NULL diff --git a/pkg/sql/logictest/testdata/logic_test/create_statements b/pkg/sql/logictest/testdata/logic_test/create_statements index b7b97f43ff35..3a7e46e6ca44 100644 --- a/pkg/sql/logictest/testdata/logic_test/create_statements +++ b/pkg/sql/logictest/testdata/logic_test/create_statements @@ -12,20 +12,20 @@ SELECT create_statement, create_nofks, alter_statements, validate_statements FRO create_statement create_nofks alter_statements validate_statements CREATE TABLE t ( a INT8 NULL, - CONSTRAINT fk_a_ref_t FOREIGN KEY (a) REFERENCES t (rowid), + CONSTRAINT fk_a_ref_t FOREIGN KEY (a) REFERENCES t(rowid), INDEX t_auto_index_fk_a_ref_t (a ASC), FAMILY "primary" (a, rowid) ) CREATE TABLE t ( a INT8 NULL, INDEX t_auto_index_fk_a_ref_t (a ASC), FAMILY "primary" (a, rowid) -) {"ALTER TABLE t ADD CONSTRAINT fk_a_ref_t FOREIGN KEY (a) REFERENCES t (rowid)"} {"ALTER TABLE t VALIDATE CONSTRAINT fk_a_ref_t"} +) {"ALTER TABLE t ADD CONSTRAINT fk_a_ref_t FOREIGN KEY (a) REFERENCES t(rowid)"} {"ALTER TABLE t VALIDATE CONSTRAINT fk_a_ref_t"} CREATE TABLE v ( "'" INT8 NULL, s STRING NULL, - CONSTRAINT fk_s_ref_v FOREIGN KEY (s) REFERENCES v (s), + CONSTRAINT fk_s_ref_v FOREIGN KEY (s) REFERENCES v(s), UNIQUE INDEX v_s_key (s ASC), - CONSTRAINT "fk_'_ref_t" FOREIGN KEY ("'") REFERENCES t (rowid), + CONSTRAINT "fk_'_ref_t" FOREIGN KEY ("'") REFERENCES t(rowid), INDEX "v_auto_index_fk_'_ref_t" ("'" ASC), FAMILY "primary" ("'", s, rowid) ) CREATE TABLE v ( @@ -34,4 +34,4 @@ CREATE TABLE v ( UNIQUE INDEX v_s_key (s ASC), INDEX "v_auto_index_fk_'_ref_t" ("'" ASC), FAMILY "primary" ("'", s, rowid) -) {"ALTER TABLE v ADD CONSTRAINT fk_s_ref_v FOREIGN KEY (s) REFERENCES v (s)","ALTER TABLE v ADD CONSTRAINT \"fk_'_ref_t\" FOREIGN KEY (\"'\") REFERENCES t (rowid)"} {"ALTER TABLE v VALIDATE CONSTRAINT fk_s_ref_v","ALTER TABLE v VALIDATE CONSTRAINT \"fk_'_ref_t\""} +) {"ALTER TABLE v ADD CONSTRAINT fk_s_ref_v FOREIGN KEY (s) REFERENCES v(s)","ALTER TABLE v ADD CONSTRAINT \"fk_'_ref_t\" FOREIGN KEY (\"'\") REFERENCES t(rowid)"} {"ALTER TABLE v VALIDATE CONSTRAINT fk_s_ref_v","ALTER TABLE v VALIDATE CONSTRAINT \"fk_'_ref_t\""} diff --git a/pkg/sql/logictest/testdata/logic_test/fk b/pkg/sql/logictest/testdata/logic_test/fk index b784d0f17b64..2952c2193fd8 100644 --- a/pkg/sql/logictest/testdata/logic_test/fk +++ b/pkg/sql/logictest/testdata/logic_test/fk @@ -188,8 +188,8 @@ CREATE TABLE "user content".review_stats ( query TTTTB SHOW CONSTRAINTS FROM "user content".review_stats ---- -review_stats primary PRIMARY KEY PRIMARY KEY (id ASC) true -review_stats reviewfk FOREIGN KEY FOREIGN KEY (id) REFERENCES "customer reviews" (id) true +review_stats primary PRIMARY KEY PRIMARY KEY (id ASC) true +review_stats reviewfk FOREIGN KEY FOREIGN KEY (id) REFERENCES "customer reviews"(id) true statement error pgcode 23503 foreign key violation: value \[5\] not found in customer reviews@primary \[id\] INSERT INTO "user content".review_stats (id, upvotes) VALUES (5, 1) @@ -258,9 +258,9 @@ delivery CREATE TABLE delivery ( "order" INT8 NULL, shipment INT8 NULL, item STRING NULL, - CONSTRAINT fk_item_ref_products FOREIGN KEY (item) REFERENCES products (upc), + CONSTRAINT fk_item_ref_products FOREIGN KEY (item) REFERENCES products(upc), INDEX delivery_item_idx (item ASC), - CONSTRAINT fk_order_ref_orders FOREIGN KEY ("order", shipment) REFERENCES orders (id, shipment), + CONSTRAINT fk_order_ref_orders FOREIGN KEY ("order", shipment) REFERENCES orders(id, shipment), INDEX delivery_auto_index_fk_order_ref_orders ("order" ASC, shipment ASC), FAMILY "primary" (ts, "order", shipment, item, rowid) ) @@ -312,7 +312,7 @@ ALTER TABLE delivery ADD FOREIGN KEY (item) REFERENCES products (upc) query TTTTB SHOW CONSTRAINTS FROM delivery ---- -delivery fk_order_ref_orders FOREIGN KEY FOREIGN KEY ("order", shipment) REFERENCES orders (id, shipment) true +delivery fk_order_ref_orders FOREIGN KEY FOREIGN KEY ("order", shipment) REFERENCES orders(id, shipment) true statement ok UPDATE products SET upc = '885155001450' WHERE sku = '780' @@ -323,8 +323,8 @@ ALTER TABLE delivery ADD FOREIGN KEY (item) REFERENCES products (upc) query TTTTB SHOW CONSTRAINTS FROM delivery ---- -delivery fk_item_ref_products FOREIGN KEY FOREIGN KEY (item) REFERENCES products (upc) true -delivery fk_order_ref_orders FOREIGN KEY FOREIGN KEY ("order", shipment) REFERENCES orders (id, shipment) true +delivery fk_item_ref_products FOREIGN KEY FOREIGN KEY (item) REFERENCES products(upc) true +delivery fk_order_ref_orders FOREIGN KEY FOREIGN KEY ("order", shipment) REFERENCES orders(id, shipment) true statement ok ALTER TABLE "user content"."customer reviews" @@ -391,10 +391,10 @@ TRUNCATE delivery, products, orders, "user content"."customer reviews" query TTTTB colnames SHOW CONSTRAINTS FROM orders ---- -table_name constraint_name constraint_type details validated -orders fk_product_ref_products FOREIGN KEY FOREIGN KEY (product) REFERENCES products (sku) ON DELETE RESTRICT ON UPDATE RESTRICT true -orders primary PRIMARY KEY PRIMARY KEY (id ASC, shipment ASC) true -orders valid_customer FOREIGN KEY FOREIGN KEY (customer) REFERENCES customers (id) true +table_name constraint_name constraint_type details validated +orders fk_product_ref_products FOREIGN KEY FOREIGN KEY (product) REFERENCES products(sku) ON DELETE RESTRICT ON UPDATE RESTRICT true +orders primary PRIMARY KEY PRIMARY KEY (id ASC, shipment ASC) true +orders valid_customer FOREIGN KEY FOREIGN KEY (customer) REFERENCES customers(id) true statement error "products_upc_key" is referenced by foreign key from table "delivery" DROP INDEX products@products_upc_key @@ -589,12 +589,12 @@ query TT SHOW CREATE TABLE refpairs ---- refpairs CREATE TABLE refpairs ( - a INT8 NULL, - b STRING NULL, - c INT8 NULL, - CONSTRAINT fk_a_ref_pairs FOREIGN KEY (a, b) REFERENCES pairs (src, dest) ON UPDATE RESTRICT, - INDEX refpairs_a_b_c_idx (a ASC, b ASC, c ASC), - FAMILY "primary" (a, b, c, rowid) + a INT8 NULL, + b STRING NULL, + c INT8 NULL, + CONSTRAINT fk_a_ref_pairs FOREIGN KEY (a, b) REFERENCES pairs(src, dest) ON UPDATE RESTRICT, + INDEX refpairs_a_b_c_idx (a ASC, b ASC, c ASC), + FAMILY "primary" (a, b, c, rowid) ) statement error pgcode 23503 foreign key violation: value \[100 'two'\] not found in pairs@pairs_src_dest_key \[src dest\] @@ -693,10 +693,10 @@ CREATE TABLE domain_modules ( query TTTTB SHOW CONSTRAINTS FROM domain_modules ---- -domain_modules domain_modules_domain_id_fk FOREIGN KEY FOREIGN KEY (domain_id) REFERENCES domains (id) true -domain_modules domain_modules_module_id_fk FOREIGN KEY FOREIGN KEY (module_id) REFERENCES modules (id) true -domain_modules domain_modules_uq UNIQUE UNIQUE (domain_id ASC, module_id ASC) true -domain_modules primary PRIMARY KEY PRIMARY KEY (id ASC) true +domain_modules domain_modules_domain_id_fk FOREIGN KEY FOREIGN KEY (domain_id) REFERENCES domains(id) true +domain_modules domain_modules_module_id_fk FOREIGN KEY FOREIGN KEY (module_id) REFERENCES modules(id) true +domain_modules domain_modules_uq UNIQUE UNIQUE (domain_id ASC, module_id ASC) true +domain_modules primary PRIMARY KEY PRIMARY KEY (id ASC) true statement ok INSERT INTO modules VALUES(3) @@ -825,7 +825,7 @@ refers CREATE TABLE refers ( a INT8 NULL, b INT8 NULL, INDEX another_idx (b ASC), - CONSTRAINT fk_a_ref_referee FOREIGN KEY (a) REFERENCES referee (id), + CONSTRAINT fk_a_ref_referee FOREIGN KEY (a) REFERENCES referee(id), INDEX refers_auto_index_fk_a_ref_referee (a ASC), INDEX foo (a ASC), FAMILY "primary" (a, b, rowid) @@ -907,7 +907,7 @@ SHOW CREATE TABLE pkref_b pkref_b CREATE TABLE pkref_b ( b INT8 NOT NULL, CONSTRAINT "primary" PRIMARY KEY (b ASC), - CONSTRAINT fk_b_ref_pkref_a FOREIGN KEY (b) REFERENCES pkref_a (a) ON DELETE RESTRICT, + CONSTRAINT fk_b_ref_pkref_a FOREIGN KEY (b) REFERENCES pkref_a(a) ON DELETE RESTRICT, FAMILY "primary" (b) ) diff --git a/pkg/sql/logictest/testdata/logic_test/pg_catalog b/pkg/sql/logictest/testdata/logic_test/pg_catalog index 8f32ba829083..b82ad46250cb 100644 --- a/pkg/sql/logictest/testdata/logic_test/pg_catalog +++ b/pkg/sql/logictest/testdata/logic_test/pg_catalog @@ -762,11 +762,11 @@ JOIN pg_catalog.pg_namespace n ON con.connamespace = n.oid WHERE n.nspname = 'public' AND contype IN ('c', 'p', 'u') ORDER BY con.oid ---- -conname confkey conpfeqop conppeqop conffeqop conexclop conbin consrc -check_b NULL NULL NULL NULL NULL b > 11 b > 11 -primary NULL NULL NULL NULL NULL NULL NULL -t1_a_key NULL NULL NULL NULL NULL NULL NULL -index_key NULL NULL NULL NULL NULL NULL NULL +conname confkey conpfeqop conppeqop conffeqop conexclop conbin consrc +check_b NULL NULL NULL NULL NULL (b > 11) (b > 11) +primary NULL NULL NULL NULL NULL NULL NULL +t1_a_key NULL NULL NULL NULL NULL NULL NULL +index_key NULL NULL NULL NULL NULL NULL NULL query TTTTTTTT colnames SELECT conname, confkey, conpfeqop, conppeqop, conffeqop, conexclop, conbin, consrc diff --git a/pkg/sql/logictest/testdata/logic_test/rename_constraint b/pkg/sql/logictest/testdata/logic_test/rename_constraint index cfd9aa336890..3dea9a3c4f8e 100644 --- a/pkg/sql/logictest/testdata/logic_test/rename_constraint +++ b/pkg/sql/logictest/testdata/logic_test/rename_constraint @@ -14,7 +14,7 @@ SELECT create_statement FROM [SHOW CREATE t] CREATE TABLE t ( x INT8 NULL, y INT8 NULL, - CONSTRAINT cf FOREIGN KEY (x) REFERENCES t (x), + CONSTRAINT cf FOREIGN KEY (x) REFERENCES t(x), UNIQUE INDEX cu (x ASC), FAMILY "primary" (x, y, rowid), CONSTRAINT cc CHECK (x > 10) @@ -40,7 +40,7 @@ SELECT create_statement FROM [SHOW CREATE t] CREATE TABLE t ( x INT8 NULL, y INT8 NULL, - CONSTRAINT cf2 FOREIGN KEY (x) REFERENCES t (x), + CONSTRAINT cf2 FOREIGN KEY (x) REFERENCES t(x), UNIQUE INDEX cu2 (x ASC), FAMILY "primary" (x, y, rowid), CONSTRAINT cc2 CHECK (x > 10) @@ -90,7 +90,7 @@ SELECT create_statement FROM [SHOW CREATE t] CREATE TABLE t ( x INT8 NULL, y INT8 NULL, - CONSTRAINT cf4 FOREIGN KEY (x) REFERENCES t (x), + CONSTRAINT cf4 FOREIGN KEY (x) REFERENCES t(x), UNIQUE INDEX cu4 (x ASC), FAMILY "primary" (x, y, rowid), CONSTRAINT cc4 CHECK (x > 10) diff --git a/pkg/sql/logictest/testdata/logic_test/schema_change_in_txn b/pkg/sql/logictest/testdata/logic_test/schema_change_in_txn index 24d492038ce4..d242af96aaac 100644 --- a/pkg/sql/logictest/testdata/logic_test/schema_change_in_txn +++ b/pkg/sql/logictest/testdata/logic_test/schema_change_in_txn @@ -40,8 +40,8 @@ COMMIT query TTTTB SHOW CONSTRAINTS FROM test.child ---- -child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent (id) false -child primary PRIMARY KEY PRIMARY KEY (id ASC) true +child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent(id) false +child primary PRIMARY KEY PRIMARY KEY (id ASC) true statement ok ALTER TABLE test.child VALIDATE CONSTRAINT fk_child_parent_id @@ -49,8 +49,8 @@ ALTER TABLE test.child VALIDATE CONSTRAINT fk_child_parent_id query TTTTB SHOW CONSTRAINTS FROM test.child ---- -child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent (id) true -child primary PRIMARY KEY PRIMARY KEY (id ASC) true +child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent(id) true +child primary PRIMARY KEY PRIMARY KEY (id ASC) true statement ok DROP TABLE test.child, test.parent @@ -89,8 +89,8 @@ SELECT * FROM test.child@child_auto_index_fk_child_parent_id query TTTTB SHOW CONSTRAINTS FROM test.child ---- -child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent (id) true -child primary PRIMARY KEY PRIMARY KEY (id ASC) true +child fk_child_parent_id FOREIGN KEY FOREIGN KEY (parent_id) REFERENCES parent(id) true +child primary PRIMARY KEY PRIMARY KEY (id ASC) true statement ok DROP TABLE test.child, test.parent @@ -294,7 +294,7 @@ SHOW CREATE TABLE b b CREATE TABLE b ( parent_id INT8 NULL, d INT8 NULL DEFAULT 23:::INT8, - CONSTRAINT fk_parent_id_ref_parent FOREIGN KEY (parent_id) REFERENCES parent (id), + CONSTRAINT fk_parent_id_ref_parent FOREIGN KEY (parent_id) REFERENCES parent(id), INDEX b_auto_index_fk_parent_id_ref_parent (parent_id ASC), INDEX foo (parent_id ASC), UNIQUE INDEX bar (parent_id ASC), @@ -918,8 +918,8 @@ COMMIT query TTTTB SHOW CONSTRAINTS FROM check_table ---- -check_table c_0 CHECK CHECK (c > 0) true -check_table d_0 CHECK CHECK (d > 0) true +check_table c_0 CHECK CHECK ((c > 0)) true +check_table d_0 CHECK CHECK ((d > 0)) true check_table primary PRIMARY KEY PRIMARY KEY (k ASC) true statement ok @@ -951,8 +951,8 @@ COMMIT query TTTTB SHOW CONSTRAINTS FROM check_table ---- -check_table c_0 CHECK CHECK (c > 0) true -check_table d_0 CHECK CHECK (d > 0) true +check_table c_0 CHECK CHECK ((c > 0)) true +check_table d_0 CHECK CHECK ((d > 0)) true check_table primary PRIMARY KEY PRIMARY KEY (k ASC) true # Adding column e was rolled back @@ -1136,9 +1136,9 @@ COMMIT query TTTTB SHOW CONSTRAINTS FROM check_table ---- -check_table ck_a CHECK CHECK (a = 0) true -check_table ck_b CHECK CHECK (b > 0) true -check_table ck_c CHECK CHECK (c > b) true +check_table ck_a CHECK CHECK ((a = 0)) true +check_table ck_b CHECK CHECK ((b > 0)) true +check_table ck_c CHECK CHECK ((c > b)) true # Also test insert/update to ensure constraint was added in a valid state (with correct column IDs, etc.) diff --git a/pkg/sql/logictest/testdata/logic_test/table b/pkg/sql/logictest/testdata/logic_test/table index 52be9585157a..fd362654c9db 100644 --- a/pkg/sql/logictest/testdata/logic_test/table +++ b/pkg/sql/logictest/testdata/logic_test/table @@ -221,11 +221,11 @@ CREATE TABLE test.dupe_generated ( query TTTTB colnames SHOW CONSTRAINTS FROM test.dupe_generated ---- -table_name constraint_name constraint_type details validated -dupe_generated check_bar CHECK CHECK (bar > 2) true -dupe_generated check_foo CHECK CHECK (foo > 2) true -dupe_generated check_foo1 CHECK CHECK (foo < 10) true -dupe_generated check_foo2 CHECK CHECK (foo > 1) true +table_name constraint_name constraint_type details validated +dupe_generated check_bar CHECK CHECK ((bar > 2)) true +dupe_generated check_foo CHECK CHECK ((foo > 2)) true +dupe_generated check_foo1 CHECK CHECK ((foo < 10)) true +dupe_generated check_foo2 CHECK CHECK ((foo > 1)) true statement ok CREATE TABLE test.named_constraints ( @@ -271,13 +271,13 @@ test.public.named_constraints CREATE TABLE named_constraints ( query TTTTB colnames SHOW CONSTRAINTS FROM test.named_constraints ---- -table_name constraint_name constraint_type details validated -named_constraints bar UNIQUE UNIQUE (id ASC, name ASC) true -named_constraints ck1 CHECK CHECK (length(nickname) < 10) true -named_constraints ck2 CHECK CHECK (length(nickname) < length(name)) true -named_constraints pk PRIMARY KEY PRIMARY KEY (id ASC) true -named_constraints uq UNIQUE UNIQUE (email ASC) true -named_constraints uq2 UNIQUE UNIQUE (username ASC) true +table_name constraint_name constraint_type details validated +named_constraints bar UNIQUE UNIQUE (id ASC, name ASC) true +named_constraints ck1 CHECK CHECK ((length(nickname) < 10)) true +named_constraints ck2 CHECK CHECK ((length(nickname) < length(name))) true +named_constraints pk PRIMARY KEY PRIMARY KEY (id ASC) true +named_constraints uq UNIQUE UNIQUE (email ASC) true +named_constraints uq2 UNIQUE UNIQUE (username ASC) true statement error duplicate constraint name: "pk" CREATE TABLE test.dupe_named_constraints ( diff --git a/pkg/sql/opt/exec/execbuilder/testdata/explain_env b/pkg/sql/opt/exec/execbuilder/testdata/explain_env index 9b3f52545893..686e470272f7 100644 --- a/pkg/sql/opt/exec/execbuilder/testdata/explain_env +++ b/pkg/sql/opt/exec/execbuilder/testdata/explain_env @@ -139,7 +139,7 @@ CREATE TABLE y ( u INT8 NOT NULL, v INT8 NULL, CONSTRAINT "primary" PRIMARY KEY (u ASC), - CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x (a), + CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x(a), INDEX y_v_idx (v ASC), FAMILY "primary" (u, v) ); @@ -220,7 +220,7 @@ CREATE TABLE y ( u INT8 NOT NULL, v INT8 NULL, CONSTRAINT "primary" PRIMARY KEY (u ASC), - CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x (a), + CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x(a), INDEX y_v_idx (v ASC), FAMILY "primary" (u, v) ); @@ -247,7 +247,7 @@ CREATE TABLE y ( u INT8 NOT NULL, v INT8 NULL, CONSTRAINT "primary" PRIMARY KEY (u ASC), - CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x (a), + CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x(a), INDEX y_v_idx (v ASC), FAMILY "primary" (u, v) ); @@ -336,7 +336,7 @@ CREATE TABLE y ( u INT8 NOT NULL, v INT8 NULL, CONSTRAINT "primary" PRIMARY KEY (u ASC), - CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x (a), + CONSTRAINT fk_v_ref_x FOREIGN KEY (v) REFERENCES x(a), INDEX y_v_idx (v ASC), FAMILY "primary" (u, v) ); diff --git a/pkg/sql/pg_catalog.go b/pkg/sql/pg_catalog.go index 06980c78f783..bc7596589093 100644 --- a/pkg/sql/pg_catalog.go +++ b/pkg/sql/pg_catalog.go @@ -813,9 +813,9 @@ CREATE TABLE pg_catalog.pg_constraint ( if conkey, err = colIDArrayToDatum(con.CheckConstraint.ColumnIDs); err != nil { return err } - consrc = tree.NewDString(con.Details) + consrc = tree.NewDString(fmt.Sprintf("(%s)", con.Details)) conbin = consrc - condef = tree.NewDString(fmt.Sprintf("CHECK (%s)", con.Details)) + condef = tree.NewDString(fmt.Sprintf("CHECK ((%s))", con.Details)) } if err := addRow( diff --git a/pkg/sql/pgwire/types.go b/pkg/sql/pgwire/types.go index ea093d4ba390..c41860ed28a0 100644 --- a/pkg/sql/pgwire/types.go +++ b/pkg/sql/pgwire/types.go @@ -176,21 +176,8 @@ func (b *writeBuffer) writeTextDatum( b.writeFromFmtCtx(b.textFormatter) case *tree.DArray: - switch d.ResolvedType().Oid() { - case oid.T_int2vector, oid.T_oidvector: - // vectors are serialized as a string of space-separated values. - sep := "" - // TODO(justin): add a test for nested arrays when #32552 is - // addressed. - for _, d := range v.Array { - b.textFormatter.WriteString(sep) - b.textFormatter.FormatNode(d) - sep = " " - } - default: - // Uses the default pgwire text format for arrays. - b.textFormatter.FormatNode(v) - } + // Arrays have custom formatting depending on their OID. + b.textFormatter.FormatNode(d) b.writeFromFmtCtx(b.textFormatter) case *tree.DOid: diff --git a/pkg/sql/sem/builtins/pg_builtins.go b/pkg/sql/sem/builtins/pg_builtins.go index c685cd782c50..2b0c714008d1 100644 --- a/pkg/sql/sem/builtins/pg_builtins.go +++ b/pkg/sql/sem/builtins/pg_builtins.go @@ -700,15 +700,23 @@ var pgBuiltins = map[string]builtinDefinition{ Types: tree.ArgTypes{{"type_oid", types.Oid}, {"typemod", types.Int}}, ReturnType: tree.FixedReturnType(types.String), Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) { + // See format_type.c in Postgres. oidArg := args[0] if oidArg == tree.DNull { return tree.DNull, nil } + maybeTypmod := args[1] typ, ok := types.OidToType[oid.Oid(int(oidArg.(*tree.DOid).DInt))] if !ok { return tree.NewDString(fmt.Sprintf("unknown (OID=%s)", oidArg)), nil } - return tree.NewDString(typ.SQLStandardName()), nil + var hasTypmod bool + var typmod int + if maybeTypmod != tree.DNull { + hasTypmod = true + typmod = int(tree.MustBeDInt(maybeTypmod)) + } + return tree.NewDString(typ.SQLStandardNameWithTypmod(hasTypmod, typmod)), nil }, Info: "Returns the SQL name of a data type that is " + "identified by its type OID and possibly a type modifier. " + @@ -871,6 +879,30 @@ SELECT description }, ), + // pg_type_is_visible returns true if the input oid corresponds to a type + // that is part of the databases on the search path, or NULL if no such type + // exists. CockroachDB doesn't support the notion of type visibility, so we + // always return true for any type oid that we support, and NULL for those + // that we don't. + // https://www.postgresql.org/docs/9.6/static/functions-info.html + "pg_type_is_visible": makeBuiltin(defProps(), + tree.Overload{ + Types: tree.ArgTypes{{"oid", types.Oid}}, + ReturnType: tree.FixedReturnType(types.Bool), + Fn: func(ctx *tree.EvalContext, args tree.Datums) (tree.Datum, error) { + oidArg := args[0] + if oidArg == tree.DNull { + return tree.DNull, nil + } + if _, ok := types.OidToType[oid.Oid(int(oidArg.(*tree.DOid).DInt))]; ok { + return tree.DBoolTrue, nil + } + return tree.DNull, nil + }, + Info: notUsableInfo, + }, + ), + "pg_sleep": makeBuiltin( tree.FunctionProperties{ // pg_sleep is marked as impure so it doesn't get executed during diff --git a/pkg/sql/sem/tree/datum.go b/pkg/sql/sem/tree/datum.go index 8370aaa01b0c..55c4966115b5 100644 --- a/pkg/sql/sem/tree/datum.go +++ b/pkg/sql/sem/tree/datum.go @@ -2993,6 +2993,9 @@ type DArray struct { // HasNonNulls is set to true if any of the datums within the are non-null. // This is used in expression serialization (FmtParsable). HasNonNulls bool + + // customOid, if non-0, is the oid of this array datum. + customOid oid.Oid } // NewDArray returns a DArray containing elements of the specified type. @@ -3026,6 +3029,12 @@ func MustBeDArray(e Expr) *DArray { // ResolvedType implements the TypedExpr interface. func (d *DArray) ResolvedType() *types.T { + switch d.customOid { + case oid.T_int2vector: + return types.Int2Vector + case oid.T_oidvector: + return types.OidVector + } return types.MakeArray(d.ParamTyp) } @@ -3514,13 +3523,19 @@ func NewDName(d string) Datum { // NewDIntVectorFromDArray is a helper routine to create a *DIntVector // (implemented as a *DOidWrapper) initialized from an existing *DArray. func NewDIntVectorFromDArray(d *DArray) Datum { - return wrapWithOid(d, oid.T_int2vector) + ret := new(DArray) + *ret = *d + ret.customOid = oid.T_int2vector + return ret } // NewDOidVectorFromDArray is a helper routine to create a *DOidVector // (implemented as a *DOidWrapper) initialized from an existing *DArray. func NewDOidVectorFromDArray(d *DArray) Datum { - return wrapWithOid(d, oid.T_oidvector) + ret := new(DArray) + *ret = *d + ret.customOid = oid.T_oidvector + return ret } // DatumTypeSize returns a lower bound on the total size of a Datum diff --git a/pkg/sql/sem/tree/eval.go b/pkg/sql/sem/tree/eval.go index 6b72607798f8..37d05cfd2c28 100644 --- a/pkg/sql/sem/tree/eval.go +++ b/pkg/sql/sem/tree/eval.go @@ -3610,11 +3610,9 @@ func (expr *IndirectionExpr) Eval(ctx *EvalContext) (Datum, error) { arr := MustBeDArray(d) // VECTOR types use 0-indexing. - if w, ok := d.(*DOidWrapper); ok { - switch w.Oid { - case oid.T_oidvector, oid.T_int2vector: - subscriptIdx++ - } + switch arr.customOid { + case oid.T_oidvector, oid.T_int2vector: + subscriptIdx++ } if subscriptIdx < 1 || subscriptIdx > arr.Len() { return DNull, nil diff --git a/pkg/sql/sem/tree/pgwire_encode.go b/pkg/sql/sem/tree/pgwire_encode.go index c2b3f5be66f9..41fe7baf1fb5 100644 --- a/pkg/sql/sem/tree/pgwire_encode.go +++ b/pkg/sql/sem/tree/pgwire_encode.go @@ -15,6 +15,8 @@ package tree import ( "bytes" "unicode/utf8" + + "github.com/lib/pq/oid" ) func (d *DTuple) pgwireFormat(ctx *FmtCtx) { @@ -88,6 +90,20 @@ func (d *DArray) pgwireFormat(ctx *FmtCtx) { // instead printed as-is. Only non-valid characters get escaped to // hex. So we delegate this formatting to a tuple-specific // string printer called pgwireFormatStringInArray(). + switch d.ResolvedType().Oid() { + case oid.T_int2vector, oid.T_oidvector: + // vectors are serialized as a string of space-separated values. + sep := "" + // TODO(justin): add a test for nested arrays when #32552 is + // addressed. + for _, d := range d.Array { + ctx.WriteString(sep) + ctx.FormatNode(d) + sep = " " + } + return + } + ctx.WriteByte('{') comma := "" for _, v := range d.Array { diff --git a/pkg/sql/show_create.go b/pkg/sql/show_create.go index 77c5591a04e2..9d24e8249755 100644 --- a/pkg/sql/show_create.go +++ b/pkg/sql/show_create.go @@ -84,7 +84,7 @@ func printForeignKeyConstraint( fmtCtx := tree.NewFmtCtx(tree.FmtSimple) fmtCtx.FormatNode(&fkTableName) buf.WriteString(fmtCtx.CloseAndGetString()) - buf.WriteString(" (") + buf.WriteString("(") formatQuoteNames(buf, refNames...) buf.WriteByte(')') idx.ColNamesString() diff --git a/pkg/sql/show_create_test.go b/pkg/sql/show_create_test.go index 612341536ae9..20b4de3e5de4 100644 --- a/pkg/sql/show_create_test.go +++ b/pkg/sql/show_create_test.go @@ -35,7 +35,7 @@ func TestStandAloneShowCreateTable(t *testing.T) { created TIMESTAMP NOT NULL DEFAULT now():::TIMESTAMP, payload BYTES NOT NULL, CONSTRAINT "primary" PRIMARY KEY (id ASC), - CONSTRAINT fk FOREIGN KEY (status) REFERENCES "[52 as ref]" ("???"), + CONSTRAINT fk FOREIGN KEY (status) REFERENCES "[52 as ref]"("???"), INDEX jobs_status_created_idx (status ASC, created ASC) INTERLEAVE IN PARENT "[51 as parent]" (status), FAMILY fam_0_id_status_created_payload (id, status, created, payload) )` diff --git a/pkg/sql/show_test.go b/pkg/sql/show_test.go index c3e624215c98..f66de6923c98 100644 --- a/pkg/sql/show_test.go +++ b/pkg/sql/show_test.go @@ -188,9 +188,9 @@ func TestShowCreateTable(t *testing.T) { i INT8 NULL, j INT8 NULL, k INT8 NULL, - CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items (a, b), + CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items(a, b), INDEX %[1]s_auto_index_fk_i_ref_items (i ASC, j ASC), - CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items (c), + CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items(c), INDEX %[1]s_auto_index_fk_k_ref_items (k ASC), FAMILY "primary" (i, j, k, rowid) )`, @@ -208,9 +208,9 @@ func TestShowCreateTable(t *testing.T) { i INT8 NULL, j INT8 NULL, k INT8 NULL, - CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items (a, b) MATCH FULL, + CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items(a, b) MATCH FULL, INDEX %[1]s_auto_index_fk_i_ref_items (i ASC, j ASC), - CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items (c) MATCH FULL, + CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items(c) MATCH FULL, INDEX %[1]s_auto_index_fk_k_ref_items (k ASC), FAMILY "primary" (i, j, k, rowid) )`, @@ -224,7 +224,7 @@ func TestShowCreateTable(t *testing.T) { )`, expect: `CREATE TABLE %s ( x INT8 NULL, - CONSTRAINT fk_ref FOREIGN KEY (x) REFERENCES o.public.foo (x), + CONSTRAINT fk_ref FOREIGN KEY (x) REFERENCES o.public.foo(x), INDEX %[1]s_auto_index_fk_ref (x ASC), FAMILY "primary" (x, rowid) )`, @@ -242,9 +242,9 @@ func TestShowCreateTable(t *testing.T) { i INT8 NULL DEFAULT 123:::INT8, j INT8 NULL DEFAULT 123:::INT8, k INT8 NULL, - CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items (a, b) ON DELETE SET DEFAULT, + CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items(a, b) ON DELETE SET DEFAULT, INDEX %[1]s_auto_index_fk_i_ref_items (i ASC, j ASC), - CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items (c) ON DELETE SET NULL, + CONSTRAINT fk_k_ref_items FOREIGN KEY (k) REFERENCES items(c) ON DELETE SET NULL, INDEX %[1]s_auto_index_fk_k_ref_items (k ASC), FAMILY "primary" (i, j, k, rowid) )`, @@ -292,9 +292,9 @@ func TestShowCreateTable(t *testing.T) { j INT8 NULL DEFAULT 2:::INT8, k INT8 NULL DEFAULT 3:::INT8, l INT8 NULL DEFAULT 4:::INT8, - CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items (a, b) ON DELETE SET DEFAULT, + CONSTRAINT fk_i_ref_items FOREIGN KEY (i, j) REFERENCES items(a, b) ON DELETE SET DEFAULT, INDEX %[1]s_auto_index_fk_i_ref_items (i ASC, j ASC), - CONSTRAINT fk_k_ref_items FOREIGN KEY (k, l) REFERENCES items (a, b) MATCH FULL ON UPDATE CASCADE, + CONSTRAINT fk_k_ref_items FOREIGN KEY (k, l) REFERENCES items(a, b) MATCH FULL ON UPDATE CASCADE, INDEX %[1]s_auto_index_fk_k_ref_items (k ASC, l ASC), FAMILY "primary" (i, j, k, l, rowid) )`, diff --git a/pkg/sql/types/types.go b/pkg/sql/types/types.go index 48ad7935088e..5c11388b2e3f 100644 --- a/pkg/sql/types/types.go +++ b/pkg/sql/types/types.go @@ -925,6 +925,24 @@ func (t *T) PGName() string { // SELECT format_type(pg_typeof(1::int)::regtype, NULL) // func (t *T) SQLStandardName() string { + return t.SQLStandardNameWithTypmod(false, 0) +} + +// SQLStandardNameWithTypmod is like SQLStandardName but it also accepts a +// typmod argument, and a boolean which indicates whether or not a typmod was +// even specified. The expected results of this function should be, in Postgres: +// +// SELECT format_type('thetype'::regype, typmod) +// +// Generally, what this does with a non-0 typmod is append the scale, precision +// or length of a datatype to the name of the datatype. For example, a +// varchar(20) would appear as character varying(20) when provided the typmod +// value for varchar(20), which happens to be 24. +// +// This function is full of special cases. See backend/utils/adt/format_type.c +// in Postgres. +func (t *T) SQLStandardNameWithTypmod(haveTypmod bool, typmod int) string { + var buf strings.Builder switch t.Family() { case AnyFamily: return "anyelement" @@ -938,9 +956,15 @@ func (t *T) SQLStandardName() string { return t.ArrayContents().SQLStandardName() + "[]" case BitFamily: if t.Oid() == oid.T_varbit { - return "bit varying" + buf.WriteString("bit varying") + } else { + buf.WriteString("bit") } - return "bit" + if !haveTypmod || typmod <= 0 { + return buf.String() + } + buf.WriteString(fmt.Sprintf("(%d)", typmod)) + return buf.String() case BoolFamily: return "boolean" case BytesFamily: @@ -948,7 +972,19 @@ func (t *T) SQLStandardName() string { case DateFamily: return "date" case DecimalFamily: - return "numeric" + if !haveTypmod || typmod <= 0 { + return "numeric" + } + // The typmod of a numeric has the precision in the upper bits and the + // scale in the lower bits of a 32-bit int, after subtracting 4 (the var + // header size). See numeric.c. + typmod -= 4 + return fmt.Sprintf( + "numeric(%d,%d)", + (typmod>>16)&0xffff, + typmod&0xffff, + ) + case FloatFamily: switch t.Width() { case 32: @@ -973,6 +1009,7 @@ func (t *T) SQLStandardName() string { panic(errors.AssertionFailedf("programming error: unknown int width: %d", t.Width())) } case IntervalFamily: + // TODO(jordan): intervals can have typmods, but we don't support them yet. return "interval" case JsonFamily: // Only binary JSON is currently supported. @@ -997,24 +1034,55 @@ func (t *T) SQLStandardName() string { case StringFamily, CollatedStringFamily: switch t.Oid() { case oid.T_text: - return "text" + buf.WriteString("text") case oid.T_varchar: - return "character varying" + buf.WriteString("character varying") case oid.T_bpchar: - return "character" + if haveTypmod && typmod < 0 { + // Special case. Run `select format_type('bpchar'::regtype, -1);` in pg. + return "bpchar" + } + buf.WriteString("character") case oid.T_char: - // Not the same as "character". Beware. + // Type modifiers not allowed for "char". return `"char"` case oid.T_name: + // Type modifiers not allowed for name. return "name" + default: + panic(errors.AssertionFailedf("unexpected OID: %d", t.Oid())) } - panic(errors.AssertionFailedf("unexpected OID: %d", t.Oid())) + if !haveTypmod { + return buf.String() + } + + // Typmod gets subtracted by 4 for all non-text string-like types to produce + // the length. + if t.Oid() != oid.T_text { + typmod -= 4 + } + if typmod <= 0 { + // In this case, we don't print any modifier. + return buf.String() + } + buf.WriteString(fmt.Sprintf("(%d)", typmod)) + return buf.String() + case TimeFamily: - return "time without time zone" + if !haveTypmod || typmod <= 0 { + return "time without time zone" + } + return fmt.Sprintf("time(%d) without time zone", typmod) case TimestampFamily: - return "timestamp without time zone" + if !haveTypmod || typmod <= 0 { + return "timestamp without time zone" + } + return fmt.Sprintf("timestamp(%d) without time zone", typmod) case TimestampTZFamily: - return "timestamp with time zone" + if !haveTypmod || typmod <= 0 { + return "timestamp with time zone" + } + return fmt.Sprintf("timestamp(%d) with time zone", typmod) case TupleFamily: return "record" case UnknownFamily: