github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/logictest/testdata/logic_test/enums (about) 1 # LogicTest: !3node-tenant 2 3 statement ok 4 SET experimental_enable_enums=true; 5 6 statement error pq: unimplemented: DROP TYPE 7 DROP TYPE mytype 8 9 statement error pq: unimplemented: DROP TYPE 10 DROP TYPE IF EXISTS mytype 11 12 statement ok 13 CREATE TYPE t AS ENUM () 14 15 statement error pq: relation "t" does not exist 16 SELECT * FROM t 17 18 statement error pq: type "t" already exists 19 CREATE TABLE t (x INT) 20 21 statement error pq: type "t" already exists 22 CREATE TYPE t AS ENUM () 23 24 statement ok 25 CREATE TABLE torename (x INT) 26 27 statement error pq: type "t" already exists 28 ALTER TABLE torename RENAME TO t 29 30 statement ok 31 CREATE DATABASE db2; 32 CREATE TYPE db2.t AS ENUM () 33 34 statement error pq: relation "db2.t" does not exist 35 SELECT * FROM db2.t 36 37 statement error pq: type "db2.public.t" already exists 38 CREATE TYPE db2.t AS ENUM () 39 40 # Regression for #48537. Dropping a table with a type name caused a panic. 41 statement error pq: relation "t" does not exist 42 DROP TABLE t 43 44 statement error pq: enum definition contains duplicate value "dup" 45 CREATE TYPE bad AS ENUM ('dup', 'dup') 46 47 # Duplicates with different casing count as different. 48 statement ok 49 CREATE TYPE notbad AS ENUM ('dup', 'DUP') 50 51 # Test that we can create types that shadow builtin type names, 52 # but in different schemas. 53 statement ok 54 CREATE TYPE int AS ENUM ('Z', 'S of int') 55 56 statement error pq: could not parse "Z" as type int 57 SELECT 'Z'::int 58 59 query T 60 SELECT 'Z'::public.int 61 ---- 62 Z 63 64 statement ok 65 CREATE TYPE greeting AS ENUM ('hello', 'howdy', 'hi') 66 67 # Test that we can only reference greeting with the right qualification. 68 statement error pq: type "pg_catalog.greeting" does not exist 69 SELECT 'hello'::pg_catalog.greeting 70 71 query T 72 SELECT 'hello'::public.greeting 73 ---- 74 hello 75 76 # Test some expression evaluation on enums. 77 # These test should live in TestEval, but it is difficult to adjust the 78 # test to handle creation of user defined types. 79 query TTT 80 SELECT 'hello'::greeting, 'howdy'::greeting, 'hi'::greeting 81 ---- 82 hello howdy hi 83 84 # Test type annotations. 85 query TTT 86 SELECT 'hello':::greeting, 'howdy':::greeting, 'hi':::greeting 87 ---- 88 hello howdy hi 89 90 statement error pq: invalid input value for enum greeting: "goodbye" 91 SELECT 'goodbye'::greeting 92 93 query T 94 SELECT 'hello'::greeting::string 95 ---- 96 hello 97 98 query BBBBBBBBBBB 99 SELECT 'hello'::greeting < 'howdy'::greeting, 100 'howdy'::greeting < 'hi', 101 'hi' > 'hello'::greeting, 102 'howdy'::greeting < 'hello'::greeting, 103 'hi'::greeting <= 'hi', 104 NULL < 'hello'::greeting, 105 'hi'::greeting < NULL, 106 'hello'::greeting = 'hello'::greeting, 107 'hello' != 'hi'::greeting, 108 'howdy'::greeting IS NOT DISTINCT FROM NULL, 109 'hello'::greeting IN ('hi'::greeting, 'howdy'::greeting, 'hello'::greeting) 110 ---- 111 true true true false true NULL NULL true true false true 112 113 statement ok 114 CREATE TYPE farewell AS ENUM ('bye', 'seeya') 115 116 statement error pq: unsupported comparison operator: <greeting> = <farewell> 117 SELECT 'hello'::greeting = 'bye'::farewell 118 119 statement error pq: unsupported comparison operator: <greeting> < <farewell> 120 SELECT 'hello'::greeting < 'bye'::farewell 121 122 statement error pq: unsupported comparison operator: <greeting> <= <farewell> 123 SELECT 'hello'::greeting <= 'bye'::farewell 124 125 query T 126 SELECT 'hello'::greeting::greeting 127 ---- 128 hello 129 130 statement ok 131 CREATE TYPE greeting2 AS ENUM ('hello') 132 133 statement error pq: invalid cast: greeting -> greeting2 134 SELECT 'hello'::greeting::greeting2 135 136 # Ensure that we can perform a limited form of implicit casts for 137 # the case of ENUM binary operations with strings. 138 query BB 139 SELECT 'hello'::greeting != 'howdy', 'hi' > 'hello'::greeting 140 ---- 141 true true 142 143 # Check that the implicit cast gives an appropriate error message 144 # when firing but unable to complete the type check. 145 statement error pq: invalid input value for enum greeting: "notagreeting" 146 SELECT 'hello'::greeting = 'notagreeting' 147 148 statement error pq: unimplemented: ALTER TYPE ADD VALUE unsupported 149 ALTER TYPE greeting ADD VALUE 'hola' AFTER 'hello' 150 151 statement error pq: unimplemented: ALTER TYPE RENAME VALUE unsupported 152 ALTER TYPE greeting RENAME VALUE 'hello' TO 'helloooooo' 153 154 statement error pq: unimplemented: ALTER TYPE RENAME unsupported 155 ALTER TYPE greeting RENAME TO greetings 156 157 statement error pq: unimplemented: ALTER TYPE SET SCHEMA unsupported 158 ALTER TYPE greeting SET SCHEMA newschema 159 160 # Tests for enum builtins. 161 statement ok 162 CREATE TYPE dbs AS ENUM ('postgres', 'mysql', 'spanner', 'cockroach') 163 164 query TT 165 SELECT enum_first('mysql'::dbs), enum_last('spanner'::dbs) 166 ---- 167 postgres cockroach 168 169 query T 170 SELECT enum_range('cockroach'::dbs) 171 ---- 172 {postgres,mysql,spanner,cockroach} 173 174 query TT 175 SELECT enum_range(NULL, 'mysql'::dbs), enum_range('spanner'::dbs, NULL) 176 ---- 177 {postgres,mysql} {spanner,cockroach} 178 179 query TT 180 SELECT enum_range('postgres'::dbs, 'spanner'::dbs), enum_range('spanner'::dbs, 'cockroach'::dbs) 181 ---- 182 {postgres,mysql,spanner} {spanner,cockroach} 183 184 query T 185 SELECT enum_range('cockroach'::dbs, 'cockroach'::dbs) 186 ---- 187 {cockroach} 188 189 query T 190 SELECT enum_range('cockroach'::dbs, 'spanner'::dbs) 191 ---- 192 {} 193 194 query error pq: enum_range\(\): both arguments cannot be NULL 195 SELECT enum_range(NULL::dbs, NULL::dbs) 196 197 query error pq: enum_range\(\): mismatched types 198 SELECT enum_range('cockroach'::dbs, 'hello'::greeting) 199 200 # Test inserting and reading enum data from tables. 201 statement ok 202 CREATE TABLE greeting_table (x1 greeting, x2 greeting) 203 204 statement error pq: invalid input value for enum greeting: "bye" 205 INSERT INTO greeting_table VALUES ('bye', 'hi') 206 207 statement ok 208 INSERT INTO greeting_table VALUES ('hi', 'hello') 209 210 query TT 211 SELECT * FROM greeting_table 212 ---- 213 hi hello 214 215 query TT 216 SELECT 'hello'::greeting, x1 FROM greeting_table 217 ---- 218 hello hi 219 220 query TB 221 SELECT x1, x1 < 'hello' FROM greeting_table 222 ---- 223 hi false 224 225 query TT 226 SELECT x1, enum_first(x1) FROM greeting_table 227 ---- 228 hi hello 229 230 statement ok 231 CREATE TABLE t1 (x greeting, INDEX i (x)); 232 CREATE TABLE t2 (x greeting, INDEX i (x)); 233 INSERT INTO t1 VALUES ('hello'); 234 INSERT INTO t2 VALUES ('hello') 235 236 query TT 237 SELECT * FROM t1 INNER LOOKUP JOIN t2 ON t1.x = t2.x 238 ---- 239 hello hello 240 241 query TT 242 SELECT * FROM t1 INNER HASH JOIN t2 ON t1.x = t2.x 243 ---- 244 hello hello 245 246 query TT 247 SELECT * FROM t1 INNER MERGE JOIN t2 ON t1.x = t2.x 248 ---- 249 hello hello 250 251 statement ok 252 INSERT INTO t2 VALUES ('hello'), ('hello'), ('howdy'), ('hi') 253 254 query T rowsort 255 SELECT DISTINCT x FROM t2 256 ---- 257 hello 258 howdy 259 hi 260 261 query T 262 SELECT DISTINCT x FROM t2 ORDER BY x DESC 263 ---- 264 hi 265 howdy 266 hello 267 268 # Test out some subqueries. 269 query T rowsort 270 SELECT x FROM t2 WHERE x > (SELECT x FROM t1 ORDER BY x LIMIT 1) 271 ---- 272 hi 273 howdy 274 275 # Test ordinality. 276 query TI 277 SELECT * FROM t2 WITH ORDINALITY ORDER BY x 278 ---- 279 hello 1 280 hello 2 281 hello 3 282 howdy 4 283 hi 5 284 285 # Test ordering with and without limits. 286 statement ok 287 INSERT INTO t1 VALUES ('hi'), ('hello'), ('howdy'), ('howdy'), ('howdy'), ('hello') 288 289 query T 290 SELECT x FROM t1 ORDER BY x DESC 291 ---- 292 hi 293 howdy 294 howdy 295 howdy 296 hello 297 hello 298 hello 299 300 query T 301 SELECT x FROM t1 ORDER BY x ASC 302 ---- 303 hello 304 hello 305 hello 306 howdy 307 howdy 308 howdy 309 hi 310 311 query T 312 SELECT x FROM t1 ORDER BY x ASC LIMIT 3 313 ---- 314 hello 315 hello 316 hello 317 318 query T 319 SELECT x FROM t1 ORDER BY x DESC LIMIT 3 320 ---- 321 hi 322 howdy 323 howdy 324 325 # Test we can group on enums. 326 query T rowsort 327 (SELECT * FROM t1) UNION (SELECT * FROM t2) 328 ---- 329 hello 330 howdy 331 hi 332 333 statement ok 334 CREATE TABLE enum_agg (x greeting, y INT); 335 INSERT INTO enum_agg VALUES 336 ('hello', 1), 337 ('hello', 3), 338 ('howdy', 5), 339 ('howdy', 0), 340 ('howdy', 1), 341 ('hi', 10) 342 343 query TIRI rowsort 344 SELECT x, max(y), sum(y), min(y) FROM enum_agg GROUP BY x 345 ---- 346 hello 3 4 1 347 howdy 5 6 0 348 hi 10 10 10 349 350 # Test aggregations on ENUM columns. 351 query TT 352 SELECT max(x), min(x) FROM enum_agg 353 ---- 354 hi hello 355 356 # Test that enums without any members can still get an aggregate 357 # resolved when distributing a flow. 358 statement ok 359 CREATE TYPE empty AS ENUM (); 360 CREATE TABLE empty_enum (x empty) 361 362 query TT 363 SELECT max(x), min(x) FROM empty_enum 364 ---- 365 NULL NULL 366 367 # Regression to ensure that statistics jobs can be run on tables 368 # with user defined types. 369 statement ok 370 CREATE TABLE greeting_stats (x greeting PRIMARY KEY); 371 INSERT INTO greeting_stats VALUES ('hi'); 372 CREATE STATISTICS s FROM greeting_stats 373 374 query T 375 SELECT x FROM greeting_stats 376 ---- 377 hi 378 379 # Test that we can cast from bytes to enum. 380 # Use a singleton enum so that the bytes encoding is simple. 381 statement ok 382 CREATE TYPE as_bytes AS ENUM ('bytes') 383 384 query TT 385 SELECT b'\x80'::as_bytes, b'\x80':::as_bytes 386 ---- 387 bytes bytes 388 389 query error pq: could not find \[255\] in enum representation 390 SELECT b'\xFF'::as_bytes 391 392 # Regression for #49300. Ensure that virtual tables have access to hydrated 393 # type descriptors. 394 query TT 395 SHOW CREATE t1 396 ---- 397 t1 CREATE TABLE t1 ( 398 x test.public.greeting NULL, 399 INDEX i (x ASC), 400 FAMILY "primary" (x, rowid) 401 ) 402 403 # SHOW CREATE uses a virtual index, so also check the code path where a 404 # descriptor scan is used. 405 query T 406 SELECT create_statement FROM crdb_internal.create_statements WHERE descriptor_name = 't1' 407 ---- 408 CREATE TABLE t1 ( 409 x test.public.greeting NULL, 410 INDEX i (x ASC), 411 FAMILY "primary" (x, rowid) 412 ) 413 414 # Test that the implicit array type has been created, and that we can use it. 415 query TT 416 SELECT ARRAY['hello']::_greeting, ARRAY['hello'::greeting] 417 ---- 418 {hello} {hello} 419 420 # Test that we can't mix enums in an array. 421 query error pq: expected 'cockroach'::test.public.dbs to be of type greeting, found type dbs 422 SELECT ARRAY['hello'::greeting, 'cockroach'::dbs] 423 424 statement ok 425 CREATE TABLE enum_array (x _greeting, y greeting[]); 426 INSERT INTO enum_array VALUES (ARRAY['hello'], ARRAY['hello']), (ARRAY['howdy'], ARRAY['howdy']) 427 428 query TT rowsort 429 SELECT * FROM enum_array 430 ---- 431 {hello} {hello} 432 {howdy} {howdy} 433 434 query TTT 435 SELECT pg_typeof(x), pg_typeof(x[1]), pg_typeof(ARRAY['hello']::_greeting) FROM enum_array LIMIT 1 436 ---- 437 test.public.greeting[] test.public.greeting test.public.greeting[] 438 439 # Ensure that the implicitly created array type will tolerate collisions. 440 # _collision will create __collision as its implicit array type, so the 441 # creation of collision will have to retry twice before it finds the open 442 # spot of ___collision for its implicit array type. 443 statement ok 444 CREATE TYPE _collision AS ENUM (); 445 CREATE TYPE collision AS ENUM (); 446 447 # _collision and __collision typelem and typarray should point back at each 448 # other, and vice versa for collision and ___collision. 449 query TOOO rowsort 450 SELECT 451 typname, oid, typelem, typarray 452 FROM 453 pg_type 454 WHERE 455 typname IN ('collision', '_collision', '__collision', '___collision') 456 ---- 457 _collision 100082 0 100083 458 __collision 100083 100082 0 459 collision 100084 0 100085 460 ___collision 100085 100084 0 461 462 # Regression for #49756. 463 query TT 464 SELECT 465 column_name, column_type 466 FROM 467 crdb_internal.table_columns 468 WHERE 469 descriptor_name = 'enum_array' AND column_name = 'x' 470 ---- 471 x family:ArrayFamily width:0 precision:0 locale:"" visible_type:0 oid:100064 array_contents:<InternalType:<family:EnumFamily width:0 precision:0 locale:"" visible_type:0 oid:100063 time_precision_is_set:false udt_metadata:<stable_type_id:63 stable_array_type_id:64 > > TypeMeta:<> > time_precision_is_set:false udt_metadata:<stable_type_id:64 stable_array_type_id:0 > 472 473 # Test tables using enums in DEFAULT expressions. 474 statement ok 475 CREATE TABLE enum_default ( 476 x INT, 477 y greeting DEFAULT 'hello', 478 z BOOL DEFAULT ('hello':::greeting IS OF (greeting, greeting)), 479 FAMILY (x, y, z) 480 ); 481 INSERT INTO enum_default VALUES (1), (2) 482 483 query ITB rowsort 484 SELECT * FROM enum_default 485 ---- 486 1 hello true 487 2 hello true 488 489 # Test that enum default values are formatted in human readable ways. 490 query TT 491 SHOW CREATE enum_default 492 ---- 493 enum_default CREATE TABLE enum_default ( 494 x INT8 NULL, 495 y test.public.greeting NULL DEFAULT 'hello':::test.public.greeting, 496 z BOOL NULL DEFAULT 'hello':::test.public.greeting IS OF (test.public.greeting, test.public.greeting), 497 FAMILY fam_0_x_y_z_rowid (x, y, z, rowid) 498 ) 499 500 # Test crdb_internal.table_columns. 501 query TT 502 SELECT 503 column_name, default_expr 504 FROM 505 crdb_internal.table_columns 506 WHERE 507 descriptor_name='enum_default' AND (column_name = 'y' OR column_name = 'z') 508 ORDER BY 509 column_name 510 ---- 511 y 'hello':::test.public.greeting 512 z 'hello':::test.public.greeting IS OF (test.public.greeting, test.public.greeting) 513 514 # Test information_schema.columns. 515 query TT 516 SELECT 517 column_name, column_default 518 FROM 519 information_schema.columns 520 WHERE 521 table_name='enum_default' AND (column_name = 'y' OR column_name = 'z') 522 ORDER BY 523 column_name 524 ---- 525 y 'hello':::test.public.greeting 526 z 'hello':::test.public.greeting IS OF (test.public.greeting, test.public.greeting) 527 528 # Test computed columns with enum values. 529 statement ok 530 CREATE TABLE enum_computed ( 531 x INT, 532 y greeting AS ('hello') STORED, 533 z BOOL AS (w = 'howdy') STORED, 534 w greeting, 535 FAMILY (x, y, z) 536 ); 537 INSERT INTO enum_computed (x, w) VALUES (1, 'hello'), (2, 'hello') 538 539 query ITBT rowsort 540 SELECT * FROM enum_computed 541 ---- 542 1 hello false hello 543 2 hello false hello 544 545 query TT 546 SHOW CREATE enum_computed 547 ---- 548 enum_computed CREATE TABLE enum_computed ( 549 x INT8 NULL, 550 y test.public.greeting NULL AS ('hello':::test.public.greeting) STORED, 551 z BOOL NULL AS (w = 'howdy':::test.public.greeting) STORED, 552 w test.public.greeting NULL, 553 FAMILY fam_0_x_y_z_w_rowid (x, y, z, w, rowid) 554 ) 555 556 # Test information_schema.columns. 557 query TT 558 SELECT 559 column_name, generation_expression 560 FROM 561 information_schema.columns 562 WHERE 563 table_name='enum_computed' AND (column_name = 'y' OR column_name = 'z') 564 ORDER BY 565 column_name 566 ---- 567 y 'hello':::test.public.greeting 568 z w = 'howdy':::test.public.greeting 569 570 # Test check constraints with enum values. 571 statement ok 572 CREATE TABLE enum_checks ( 573 x greeting, 574 CHECK (x = 'hello'::greeting), 575 CHECK ('hello':::greeting = 'hello':::greeting) 576 ); 577 INSERT INTO enum_checks VALUES ('hello') 578 579 query TT 580 SHOW CREATE enum_checks 581 ---- 582 enum_checks CREATE TABLE enum_checks ( 583 x test.public.greeting NULL, 584 FAMILY "primary" (x, rowid), 585 CONSTRAINT check_x CHECK (x = 'hello':::test.public.greeting::test.public.greeting), 586 CONSTRAINT "check" CHECK ('hello':::test.public.greeting = 'hello':::test.public.greeting) 587 )