make -C ./src/backend generated-headers make[1]: Entering directory '/build/postgresql/src/postgresql-13.5/src/backend' make -C catalog distprep generated-header-symlinks make -C utils distprep generated-header-symlinks make[2]: Entering directory '/build/postgresql/src/postgresql-13.5/src/backend/utils' make[2]: Nothing to be done for 'distprep'. make[2]: Nothing to be done for 'generated-header-symlinks'. make[2]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/backend/utils' make[2]: Entering directory '/build/postgresql/src/postgresql-13.5/src/backend/catalog' make[2]: Nothing to be done for 'distprep'. make[2]: Nothing to be done for 'generated-header-symlinks'. make[2]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/backend/catalog' make[1]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/backend' rm -rf '/build/postgresql/src/postgresql-13.5'/tmp_install /usr/bin/mkdir -p '/build/postgresql/src/postgresql-13.5'/tmp_install/log make -C '.' DESTDIR='/build/postgresql/src/postgresql-13.5'/tmp_install install >'/build/postgresql/src/postgresql-13.5'/tmp_install/log/install.log 2>&1 make -j1 -C src/test/regress checkprep >>'/build/postgresql/src/postgresql-13.5'/tmp_install/log/install.log 2>&1 make -C src/test/regress check make[1]: Entering directory '/build/postgresql/src/postgresql-13.5/src/test/regress' make -C ../../../src/port all rm -rf ./testtablespace mkdir ./testtablespace make[2]: Entering directory '/build/postgresql/src/postgresql-13.5/src/port' make[2]: Nothing to be done for 'all'. make[2]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/port' make -C ../../../src/common all make[2]: Entering directory '/build/postgresql/src/postgresql-13.5/src/common' make[2]: Nothing to be done for 'all'. make[2]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/common' make -C ../../../contrib/spi make[2]: Entering directory '/build/postgresql/src/postgresql-13.5/contrib/spi' make[2]: Nothing to be done for 'all'. make[2]: Leaving directory '/build/postgresql/src/postgresql-13.5/contrib/spi' PATH="/build/postgresql/src/postgresql-13.5/tmp_install/usr/bin:$PATH" LD_LIBRARY_PATH="/build/postgresql/src/postgresql-13.5/tmp_install/usr/lib" ../../../src/test/regress/pg_regress --temp-instance=./tmp_check --inputdir=. --bindir= --dlpath=. --max-concurrent-tests=20 --schedule=./parallel_schedule pg_regress: could not set core size: disallowed by hard limit ============== creating temporary instance ============== ============== initializing database system ============== ============== starting postmaster ============== running on port 64469 with PID 69722 ============== creating database "regression" ============== CREATE DATABASE ALTER DATABASE ============== running regression test queries ============== test tablespace ... ok 925 ms parallel group (20 tests): int4 int2 regproc oid text char name int8 money varchar txid pg_lsn float4 uuid float8 enum boolean bit numeric rangetypes boolean ... FAILED (test process exited with exit code 2) 409 ms char ... ok 221 ms name ... ok 251 ms varchar ... ok 260 ms text ... ok 218 ms int2 ... ok 203 ms int4 ... ok 196 ms int8 ... ok 250 ms oid ... ok 216 ms float4 ... ok 271 ms float8 ... ok 294 ms bit ... FAILED (test process exited with exit code 2) 422 ms numeric ... ok 823 ms txid ... ok 258 ms uuid ... ok 277 ms enum ... ok 347 ms money ... ok 255 ms rangetypes ... FAILED (test process exited with exit code 2) 1348 ms pg_lsn ... ok 265 ms regproc ... ok 206 ms parallel group (20 tests): line timetz time macaddr path circle lseg macaddr8 tstypes date xid inet interval numerology strings point timestamp timestamptz box polygon strings ... ok 419 ms numerology ... FAILED (test process exited with exit code 2) 407 ms point ... FAILED (test process exited with exit code 2) 433 ms lseg ... ok 214 ms line ... ok 176 ms box ... FAILED (test process exited with exit code 2) 1283 ms path ... ok 211 ms polygon ... FAILED (test process exited with exit code 2) 1775 ms circle ... ok 211 ms date ... ok 283 ms time ... ok 199 ms timetz ... ok 186 ms timestamp ... ok 633 ms timestamptz ... ok 671 ms interval ... FAILED (test process exited with exit code 2) 394 ms inet ... ok 300 ms macaddr ... ok 207 ms macaddr8 ... ok 237 ms tstypes ... ok 270 ms xid ... ok 294 ms parallel group (10 tests): comments unicode expressions misc_sanity horology type_sanity oidjoins geometry regex opr_sanity geometry ... FAILED (test process exited with exit code 2) 601 ms horology ... FAILED (test process exited with exit code 2) 373 ms regex ... ok 719 ms oidjoins ... ok 497 ms type_sanity ... FAILED (test process exited with exit code 2) 374 ms opr_sanity ... ok 1052 ms misc_sanity ... ok 319 ms comments ... ok 111 ms expressions ... ok 228 ms unicode ... ok 136 ms test create_function_1 ... ok 111 ms test create_type ... ok 180 ms test create_table ... ok 1078 ms test create_function_2 ... ok 113 ms parallel group (5 tests): copydml copyselect insert_conflict insert copy copy ... ok 1031 ms copyselect ... ok 202 ms copydml ... ok 199 ms insert ... ok 943 ms insert_conflict ... ok 452 ms parallel group (3 tests): create_operator create_procedure create_misc create_misc ... ok 302 ms create_operator ... ok 154 ms create_procedure ... ok 232 ms parallel group (5 tests): create_view index_including create_index create_index_spgist index_including_gist create_index ... FAILED (test process exited with exit code 2) 979 ms create_index_spgist ... FAILED (test process exited with exit code 2) 1063 ms create_view ... ok 812 ms index_including ... ok 852 ms index_including_gist ... ok 1468 ms parallel group (16 tests): errors roleattributes create_cast hash_func create_aggregate drop_if_exists create_function_3 typed_table create_am select infinite_recurse constraints vacuum inherit updatable_views triggers create_aggregate ... ok 276 ms create_function_3 ... ok 318 ms create_cast ... ok 187 ms constraints ... ok 549 ms triggers ... ok 1642 ms select ... FAILED (test process exited with exit code 2) 495 ms inherit ... FAILED (test process exited with exit code 2) 1316 ms typed_table ... ok 423 ms vacuum ... ok 978 ms drop_if_exists ... ok 276 ms updatable_views ... ok 1402 ms roleattributes ... ok 174 ms create_am ... ok 425 ms hash_func ... ok 230 ms errors ... ok 162 ms infinite_recurse ... ok 512 ms test sanity_check ... FAILED 498 ms parallel group (20 tests): select_distinct_on select_having random delete case namespace select_implicit select_into transactions select_distinct prepared_xacts portals btree_index join union update arrays subselect hash_index aggregates select_into ... ok 335 ms select_distinct ... FAILED (test process exited with exit code 2) 429 ms select_distinct_on ... ok 205 ms select_implicit ... ok 279 ms select_having ... ok 217 ms subselect ... ok 802 ms union ... ok 577 ms case ... ok 256 ms join ... FAILED (test process exited with exit code 2) 500 ms aggregates ... FAILED (test process exited with exit code 2) 1201 ms transactions ... ok 421 ms random ... ok 225 ms portals ... ok 483 ms arrays ... ok 678 ms btree_index ... FAILED (test process exited with exit code 2) 493 ms hash_index ... ok 802 ms update ... FAILED (test process exited with exit code 2) 594 ms delete ... ok 236 ms namespace ... ok 260 ms prepared_xacts ... ok 444 ms parallel group (20 tests): init_privs security_label drop_operator groupingsets password tablesample object_address replica_identity identity collate matview generated gin rowsecurity spgist privileges join_hash gist lock brin brin ... ok 56503 ms gin ... FAILED (test process exited with exit code 2) 1191 ms gist ... ok 4249 ms spgist ... ok 1635 ms privileges ... ok 2490 ms init_privs ... ok 171 ms security_label ... ok 211 ms collate ... FAILED (test process exited with exit code 2) 705 ms matview ... ok 918 ms lock ... ok 56466 ms replica_identity ... ok 578 ms rowsecurity ... ok 1284 ms object_address ... ok 504 ms tablesample ... ok 502 ms groupingsets ... FAILED (test process exited with exit code 2) 479 ms drop_operator ... ok 236 ms password ... ok 484 ms identity ... ok 690 ms generated ... ok 1133 ms join_hash ... FAILED (test process exited with exit code 2) 3193 ms parallel group (13 tests): async dbsize alter_operator tid tsrf tidscan alter_generic incremental_sort sysviews misc_functions misc collate.icu.utf8 create_table_like create_table_like ... ok 789 ms alter_generic ... ok 382 ms alter_operator ... ok 195 ms misc ... FAILED (test process exited with exit code 2) 579 ms async ... ok 139 ms dbsize ... ok 149 ms misc_functions ... ok 526 ms sysviews ... ok 495 ms tsrf ... ok 262 ms tid ... ok 221 ms tidscan ... ok 302 ms collate.icu.utf8 ... FAILED (test process exited with exit code 2) 620 ms incremental_sort ... FAILED (test process exited with exit code 2) 484 ms parallel group (6 tests): collate.linux.utf8 amutils psql_crosstab psql rules stats_ext rules ... FAILED 1005 ms psql ... ok 727 ms psql_crosstab ... ok 209 ms amutils ... FAILED 163 ms stats_ext ... ok 2942 ms collate.linux.utf8 ... ok 119 ms test select_parallel ... FAILED (test process exited with exit code 2) 558 ms test write_parallel ... ok 330 ms parallel group (2 tests): subscription publication publication ... ok 392 ms subscription ... ok 159 ms parallel group (17 tests): portals_p2 advisory_lock tsdicts combocid guc xmlmap equivclass dependency functional_deps tsearch select_views window cluster bitmapops indirect_toast foreign_data foreign_key select_views ... ok 702 ms portals_p2 ... ok 184 ms foreign_key ... ok 2055 ms cluster ... ok 842 ms dependency ... ok 361 ms guc ... ok 269 ms bitmapops ... ok 916 ms combocid ... ok 264 ms tsearch ... FAILED (test process exited with exit code 2) 443 ms tsdicts ... ok 259 ms foreign_data ... ok 1395 ms window ... ok 799 ms xmlmap ... ok 295 ms functional_deps ... ok 360 ms advisory_lock ... ok 204 ms indirect_toast ... ok 1345 ms equivclass ... ok 351 ms parallel group (6 tests): jsonpath_encoding json_encoding jsonpath jsonb_jsonpath json jsonb json ... ok 381 ms jsonb ... ok 724 ms json_encoding ... ok 125 ms jsonpath ... ok 155 ms jsonpath_encoding ... ok 115 ms jsonb_jsonpath ... ok 280 ms parallel group (18 tests): conversion prepare returning plancache limit sequence temp largeobject copy2 rowtypes polymorphism with truncate rangefuncs domain xml plpgsql alter_table plancache ... ok 404 ms limit ... ok 428 ms plpgsql ... ok 1487 ms copy2 ... ok 565 ms temp ... ok 504 ms domain ... ok 760 ms rangefuncs ... FAILED (test process exited with exit code 2) 692 ms prepare ... ok 269 ms conversion ... ok 138 ms truncate ... ok 672 ms alter_table ... FAILED 2906 ms sequence ... ok 495 ms polymorphism ... ok 636 ms rowtypes ... ok 572 ms returning ... ok 366 ms largeobject ... ok 534 ms with ... FAILED (test process exited with exit code 2) 663 ms xml ... ok 1306 ms parallel group (9 tests): hash_part reloptions partition_info explain indexing partition_join partition_prune partition_aggregate tuplesort partition_join ... ok 1973 ms partition_prune ... FAILED (test process exited with exit code 2) 2021 ms reloptions ... ok 235 ms hash_part ... ok 193 ms indexing ... ok 1602 ms partition_aggregate ... ok 2198 ms partition_info ... ok 270 ms tuplesort ... ok 3454 ms explain ... ok 284 ms test event_trigger ... ok 444 ms test fast_default ... ok 461 ms test stats ... ok 824 ms ============== shutting down postmaster ============== ========================= 36 of 201 tests failed. ========================= The differences that caused some tests to fail can be viewed in the file "/build/postgresql/src/postgresql-13.5/src/test/regress/regression.diffs". A copy of the test summary that you see above is saved in the file "/build/postgresql/src/postgresql-13.5/src/test/regress/regression.out". make[1]: *** [GNUmakefile:132: check] Error 1 make[1]: Leaving directory '/build/postgresql/src/postgresql-13.5/src/test/regress' make: *** [GNUmakefile:69: check] Error 2 make check failure: ./src/test/regress/regression.diffs diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/boolean.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/boolean.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/boolean.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/boolean.out 2022-02-13 01:11:57.275472240 +0100 @@ -295,265 +295,8 @@ SELECT '' AS tf_12, BOOLTBL1.*, BOOLTBL2.* FROM BOOLTBL1, BOOLTBL2 WHERE BOOLTBL2.f1 <> BOOLTBL1.f1; - tf_12 | f1 | f1 --------+----+---- - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f -(12 rows) - -SELECT '' AS tf_12, BOOLTBL1.*, BOOLTBL2.* - FROM BOOLTBL1, BOOLTBL2 - WHERE boolne(BOOLTBL2.f1,BOOLTBL1.f1); - tf_12 | f1 | f1 --------+----+---- - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f -(12 rows) - -SELECT '' AS ff_4, BOOLTBL1.*, BOOLTBL2.* - FROM BOOLTBL1, BOOLTBL2 - WHERE BOOLTBL2.f1 = BOOLTBL1.f1 and BOOLTBL1.f1 = bool 'false'; - ff_4 | f1 | f1 -------+----+---- - | f | f - | f | f - | f | f - | f | f -(4 rows) - -SELECT '' AS tf_12_ff_4, BOOLTBL1.*, BOOLTBL2.* - FROM BOOLTBL1, BOOLTBL2 - WHERE BOOLTBL2.f1 = BOOLTBL1.f1 or BOOLTBL1.f1 = bool 'true' - ORDER BY BOOLTBL1.f1, BOOLTBL2.f1; - tf_12_ff_4 | f1 | f1 -------------+----+---- - | f | f - | f | f - | f | f - | f | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f - | t | f -(16 rows) - --- --- SQL syntax --- Try all combinations to ensure that we get nothing when we expect nothing --- - thomas 2000-01-04 --- -SELECT '' AS "True", f1 - FROM BOOLTBL1 - WHERE f1 IS TRUE; - True | f1 -------+---- - | t - | t - | t -(3 rows) - -SELECT '' AS "Not False", f1 - FROM BOOLTBL1 - WHERE f1 IS NOT FALSE; - Not False | f1 ------------+---- - | t - | t - | t -(3 rows) - -SELECT '' AS "False", f1 - FROM BOOLTBL1 - WHERE f1 IS FALSE; - False | f1 --------+---- - | f -(1 row) - -SELECT '' AS "Not True", f1 - FROM BOOLTBL1 - WHERE f1 IS NOT TRUE; - Not True | f1 -----------+---- - | f -(1 row) - -SELECT '' AS "True", f1 - FROM BOOLTBL2 - WHERE f1 IS TRUE; - True | f1 -------+---- -(0 rows) - -SELECT '' AS "Not False", f1 - FROM BOOLTBL2 - WHERE f1 IS NOT FALSE; - Not False | f1 ------------+---- -(0 rows) - -SELECT '' AS "False", f1 - FROM BOOLTBL2 - WHERE f1 IS FALSE; - False | f1 --------+---- - | f - | f - | f - | f -(4 rows) - -SELECT '' AS "Not True", f1 - FROM BOOLTBL2 - WHERE f1 IS NOT TRUE; - Not True | f1 -----------+---- - | f - | f - | f - | f -(4 rows) - --- --- Tests for BooleanTest --- -CREATE TABLE BOOLTBL3 (d text, b bool, o int); -INSERT INTO BOOLTBL3 (d, b, o) VALUES ('true', true, 1); -INSERT INTO BOOLTBL3 (d, b, o) VALUES ('false', false, 2); -INSERT INTO BOOLTBL3 (d, b, o) VALUES ('null', null, 3); -SELECT - d, - b IS TRUE AS istrue, - b IS NOT TRUE AS isnottrue, - b IS FALSE AS isfalse, - b IS NOT FALSE AS isnotfalse, - b IS UNKNOWN AS isunknown, - b IS NOT UNKNOWN AS isnotunknown -FROM booltbl3 ORDER BY o; - d | istrue | isnottrue | isfalse | isnotfalse | isunknown | isnotunknown --------+--------+-----------+---------+------------+-----------+-------------- - true | t | f | f | t | f | t - false | f | t | t | f | f | t - null | f | t | f | t | t | f -(3 rows) - --- Test to make sure short-circuiting and NULL handling is --- correct. Use a table as source to prevent constant simplification --- to interfer. -CREATE TABLE booltbl4(isfalse bool, istrue bool, isnul bool); -INSERT INTO booltbl4 VALUES (false, true, null); -\pset null '(null)' --- AND expression need to return null if there's any nulls and not all --- of the value are true -SELECT istrue AND isnul AND istrue FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT istrue AND istrue AND isnul FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT isnul AND istrue AND istrue FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT isfalse AND isnul AND istrue FROM booltbl4; - ?column? ----------- - f -(1 row) - -SELECT istrue AND isfalse AND isnul FROM booltbl4; - ?column? ----------- - f -(1 row) - -SELECT isnul AND istrue AND isfalse FROM booltbl4; - ?column? ----------- - f -(1 row) - --- OR expression need to return null if there's any nulls and none --- of the value is true -SELECT isfalse OR isnul OR isfalse FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT isfalse OR isfalse OR isnul FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT isnul OR isfalse OR isfalse FROM booltbl4; - ?column? ----------- - (null) -(1 row) - -SELECT isfalse OR isnul OR istrue FROM booltbl4; - ?column? ----------- - t -(1 row) - -SELECT istrue OR isfalse OR isnul FROM booltbl4; - ?column? ----------- - t -(1 row) - -SELECT isnul OR istrue OR isfalse FROM booltbl4; - ?column? ----------- - t -(1 row) - --- --- Clean up --- Many tables are retained by the regression test, but these do not seem --- particularly useful so just get rid of them for now. --- - thomas 1997-11-30 --- -DROP TABLE BOOLTBL1; -DROP TABLE BOOLTBL2; -DROP TABLE BOOLTBL3; -DROP TABLE BOOLTBL4; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/bit.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/bit.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/bit.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/bit.out 2022-02-13 01:11:57.292138935 +0100 @@ -44,692 +44,8 @@ SELECT v, b, (v || b) AS concat FROM BIT_TABLE, VARBIT_TABLE ORDER BY 3; - v | b | concat --------------+-------------+------------------------ - | 00000000000 | 00000000000 - 0 | 00000000000 | 000000000000 - 0 | 01010101010 | 001010101010 - 010101 | 00000000000 | 01010100000000000 - | 01010101010 | 01010101010 - 01010101010 | 00000000000 | 0101010101000000000000 - 01010101010 | 01010101010 | 0101010101001010101010 - 010101 | 01010101010 | 01010101010101010 - 01010101010 | 11011000000 | 0101010101011011000000 - 010101 | 11011000000 | 01010111011000000 - 0 | 11011000000 | 011011000000 - | 11011000000 | 11011000000 -(12 rows) - --- Length -SELECT b, length(b) AS lb - FROM BIT_TABLE; - b | lb --------------+---- - 00000000000 | 11 - 11011000000 | 11 - 01010101010 | 11 -(3 rows) - -SELECT v, length(v) AS lv - FROM VARBIT_TABLE; - v | lv --------------+---- - | 0 - 0 | 1 - 010101 | 6 - 01010101010 | 11 -(4 rows) - --- Substring -SELECT b, - SUBSTRING(b FROM 2 FOR 4) AS sub_2_4, - SUBSTRING(b FROM 7 FOR 13) AS sub_7_13, - SUBSTRING(b FROM 6) AS sub_6 - FROM BIT_TABLE; - b | sub_2_4 | sub_7_13 | sub_6 --------------+---------+----------+-------- - 00000000000 | 0000 | 00000 | 000000 - 11011000000 | 1011 | 00000 | 000000 - 01010101010 | 1010 | 01010 | 101010 -(3 rows) - -SELECT v, - SUBSTRING(v FROM 2 FOR 4) AS sub_2_4, - SUBSTRING(v FROM 7 FOR 13) AS sub_7_13, - SUBSTRING(v FROM 6) AS sub_6 - FROM VARBIT_TABLE; - v | sub_2_4 | sub_7_13 | sub_6 --------------+---------+----------+-------- - | | | - 0 | | | - 010101 | 1010 | | 1 - 01010101010 | 1010 | 01010 | 101010 -(4 rows) - --- test overflow cases -SELECT SUBSTRING('01010101'::bit(8) FROM 2 FOR 2147483646) AS "1010101"; - 1010101 ---------- - 1010101 -(1 row) - -SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR 2147483646) AS "01010101"; - 01010101 ----------- - 01010101 -(1 row) - -SELECT SUBSTRING('01010101'::bit(8) FROM -10 FOR -2147483646) AS "error"; -ERROR: negative substring length not allowed -SELECT SUBSTRING('01010101'::varbit FROM 2 FOR 2147483646) AS "1010101"; - 1010101 ---------- - 1010101 -(1 row) - -SELECT SUBSTRING('01010101'::varbit FROM -10 FOR 2147483646) AS "01010101"; - 01010101 ----------- - 01010101 -(1 row) - -SELECT SUBSTRING('01010101'::varbit FROM -10 FOR -2147483646) AS "error"; -ERROR: negative substring length not allowed ---- Bit operations -DROP TABLE varbit_table; -CREATE TABLE varbit_table (a BIT VARYING(16), b BIT VARYING(16)); -COPY varbit_table FROM stdin; -SELECT a, b, ~a AS "~ a", a & b AS "a & b", - a | b AS "a | b", a # b AS "a # b" FROM varbit_table; - a | b | ~ a | a & b | a | b | a # b -------------------+------------------+------------------+------------------+------------------+------------------ - 00001111 | 00010000 | 11110000 | 00000000 | 00011111 | 00011111 - 00011111 | 00010001 | 11100000 | 00010001 | 00011111 | 00001110 - 00101111 | 00010010 | 11010000 | 00000010 | 00111111 | 00111101 - 00111111 | 00010011 | 11000000 | 00010011 | 00111111 | 00101100 - 10001111 | 00000100 | 01110000 | 00000100 | 10001111 | 10001011 - 0000000000001111 | 0000000000010000 | 1111111111110000 | 0000000000000000 | 0000000000011111 | 0000000000011111 - 0000000100100011 | 1111111111111111 | 1111111011011100 | 0000000100100011 | 1111111111111111 | 1111111011011100 - 0010010001101000 | 0010010001101000 | 1101101110010111 | 0010010001101000 | 0010010001101000 | 0000000000000000 - 1111101001010000 | 0000010110101111 | 0000010110101111 | 0000000000000000 | 1111111111111111 | 1111111111111111 - 0001001000110100 | 1111111111110101 | 1110110111001011 | 0001001000110100 | 1111111111110101 | 1110110111000001 -(10 rows) - -SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM varbit_table; - a | b | a=b | a>b | a<>b -------------------+------------------+-----+------+-----+------+-----+------ - 00001111 | 00010000 | t | t | f | f | f | t - 00011111 | 00010001 | f | f | f | t | t | t - 00101111 | 00010010 | f | f | f | t | t | t - 00111111 | 00010011 | f | f | f | t | t | t - 10001111 | 00000100 | f | f | f | t | t | t - 0000000000001111 | 0000000000010000 | t | t | f | f | f | t - 0000000100100011 | 1111111111111111 | t | t | f | f | f | t - 0010010001101000 | 0010010001101000 | f | t | t | t | f | f - 1111101001010000 | 0000010110101111 | f | f | f | t | t | t - 0001001000110100 | 1111111111110101 | t | t | f | f | f | t -(10 rows) - -SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM varbit_table; - a | a<<4 | b | b>>2 -------------------+------------------+------------------+------------------ - 00001111 | 11110000 | 00010000 | 00000100 - 00011111 | 11110000 | 00010001 | 00000100 - 00101111 | 11110000 | 00010010 | 00000100 - 00111111 | 11110000 | 00010011 | 00000100 - 10001111 | 11110000 | 00000100 | 00000001 - 0000000000001111 | 0000000011110000 | 0000000000010000 | 0000000000000100 - 0000000100100011 | 0001001000110000 | 1111111111111111 | 0011111111111111 - 0010010001101000 | 0100011010000000 | 0010010001101000 | 0000100100011010 - 1111101001010000 | 1010010100000000 | 0000010110101111 | 0000000101101011 - 0001001000110100 | 0010001101000000 | 1111111111110101 | 0011111111111101 -(10 rows) - -DROP TABLE varbit_table; ---- Bit operations -DROP TABLE bit_table; -CREATE TABLE bit_table (a BIT(16), b BIT(16)); -COPY bit_table FROM stdin; -SELECT a,b,~a AS "~ a",a & b AS "a & b", - a|b AS "a | b", a # b AS "a # b" FROM bit_table; - a | b | ~ a | a & b | a | b | a # b -------------------+------------------+------------------+------------------+------------------+------------------ - 0000111100000000 | 0001000000000000 | 1111000011111111 | 0000000000000000 | 0001111100000000 | 0001111100000000 - 0001111100000000 | 0001000100000000 | 1110000011111111 | 0001000100000000 | 0001111100000000 | 0000111000000000 - 0010111100000000 | 0001001000000000 | 1101000011111111 | 0000001000000000 | 0011111100000000 | 0011110100000000 - 0011111100000000 | 0001001100000000 | 1100000011111111 | 0001001100000000 | 0011111100000000 | 0010110000000000 - 1000111100000000 | 0000010000000000 | 0111000011111111 | 0000010000000000 | 1000111100000000 | 1000101100000000 - 0000000000001111 | 0000000000010000 | 1111111111110000 | 0000000000000000 | 0000000000011111 | 0000000000011111 - 0000000100100011 | 1111111111111111 | 1111111011011100 | 0000000100100011 | 1111111111111111 | 1111111011011100 - 0010010001101000 | 0010010001101000 | 1101101110010111 | 0010010001101000 | 0010010001101000 | 0000000000000000 - 1111101001010000 | 0000010110101111 | 0000010110101111 | 0000000000000000 | 1111111111111111 | 1111111111111111 - 0001001000110100 | 1111111111110101 | 1110110111001011 | 0001001000110100 | 1111111111110101 | 1110110111000001 -(10 rows) - -SELECT a,b,a=b AS "a>=b",a>b AS "a>b",a<>b AS "a<>b" FROM bit_table; - a | b | a=b | a>b | a<>b -------------------+------------------+-----+------+-----+------+-----+------ - 0000111100000000 | 0001000000000000 | t | t | f | f | f | t - 0001111100000000 | 0001000100000000 | f | f | f | t | t | t - 0010111100000000 | 0001001000000000 | f | f | f | t | t | t - 0011111100000000 | 0001001100000000 | f | f | f | t | t | t - 1000111100000000 | 0000010000000000 | f | f | f | t | t | t - 0000000000001111 | 0000000000010000 | t | t | f | f | f | t - 0000000100100011 | 1111111111111111 | t | t | f | f | f | t - 0010010001101000 | 0010010001101000 | f | t | t | t | f | f - 1111101001010000 | 0000010110101111 | f | f | f | t | t | t - 0001001000110100 | 1111111111110101 | t | t | f | f | f | t -(10 rows) - -SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM bit_table; - a | a<<4 | b | b>>2 -------------------+------------------+------------------+------------------ - 0000111100000000 | 1111000000000000 | 0001000000000000 | 0000010000000000 - 0001111100000000 | 1111000000000000 | 0001000100000000 | 0000010001000000 - 0010111100000000 | 1111000000000000 | 0001001000000000 | 0000010010000000 - 0011111100000000 | 1111000000000000 | 0001001100000000 | 0000010011000000 - 1000111100000000 | 1111000000000000 | 0000010000000000 | 0000000100000000 - 0000000000001111 | 0000000011110000 | 0000000000010000 | 0000000000000100 - 0000000100100011 | 0001001000110000 | 1111111111111111 | 0011111111111111 - 0010010001101000 | 0100011010000000 | 0010010001101000 | 0000100100011010 - 1111101001010000 | 1010010100000000 | 0000010110101111 | 0000000101101011 - 0001001000110100 | 0010001101000000 | 1111111111110101 | 0011111111111101 -(10 rows) - -DROP TABLE bit_table; --- The following should fail -select B'001' & B'10'; -ERROR: cannot AND bit strings of different sizes -select B'0111' | B'011'; -ERROR: cannot OR bit strings of different sizes -select B'0010' # B'011101'; -ERROR: cannot XOR bit strings of different sizes --- More position tests, checking all the boundary cases -SELECT POSITION(B'1010' IN B'0000101'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'1010' IN B'00001010'); -- 5 - position ----------- - 5 -(1 row) - -SELECT POSITION(B'1010' IN B'00000101'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'1010' IN B'000001010'); -- 6 - position ----------- - 6 -(1 row) - -SELECT POSITION(B'' IN B'00001010'); -- 1 - position ----------- - 1 -(1 row) - -SELECT POSITION(B'0' IN B''); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'' IN B''); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'101101' IN B'001011011011011000'); -- 3 - position ----------- - 3 -(1 row) - -SELECT POSITION(B'10110110' IN B'001011011011010'); -- 3 - position ----------- - 3 -(1 row) - -SELECT POSITION(B'1011011011011' IN B'001011011011011'); -- 3 - position ----------- - 3 -(1 row) - -SELECT POSITION(B'1011011011011' IN B'00001011011011011'); -- 5 - position ----------- - 5 -(1 row) - -SELECT POSITION(B'11101011' IN B'11101011'); -- 1 - position ----------- - 1 -(1 row) - -SELECT POSITION(B'11101011' IN B'011101011'); -- 2 - position ----------- - 2 -(1 row) - -SELECT POSITION(B'11101011' IN B'00011101011'); -- 4 - position ----------- - 4 -(1 row) - -SELECT POSITION(B'11101011' IN B'0000011101011'); -- 6 - position ----------- - 6 -(1 row) - -SELECT POSITION(B'111010110' IN B'111010110'); -- 1 - position ----------- - 1 -(1 row) - -SELECT POSITION(B'111010110' IN B'0111010110'); -- 2 - position ----------- - 2 -(1 row) - -SELECT POSITION(B'111010110' IN B'000111010110'); -- 4 - position ----------- - 4 -(1 row) - -SELECT POSITION(B'111010110' IN B'00000111010110'); -- 6 - position ----------- - 6 -(1 row) - -SELECT POSITION(B'111010110' IN B'11101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'011101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'00011101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'0000011101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'111010110'); -- 1 - position ----------- - 1 -(1 row) - -SELECT POSITION(B'111010110' IN B'0111010110'); -- 2 - position ----------- - 2 -(1 row) - -SELECT POSITION(B'111010110' IN B'000111010110'); -- 4 - position ----------- - 4 -(1 row) - -SELECT POSITION(B'111010110' IN B'00000111010110'); -- 6 - position ----------- - 6 -(1 row) - -SELECT POSITION(B'111010110' IN B'000001110101111101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'0000001110101111101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'000000001110101111101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'00000000001110101111101011'); -- 0 - position ----------- - 0 -(1 row) - -SELECT POSITION(B'111010110' IN B'0000011101011111010110'); -- 14 - position ----------- - 14 -(1 row) - -SELECT POSITION(B'111010110' IN B'00000011101011111010110'); -- 15 - position ----------- - 15 -(1 row) - -SELECT POSITION(B'111010110' IN B'0000000011101011111010110'); -- 17 - position ----------- - 17 -(1 row) - -SELECT POSITION(B'111010110' IN B'000000000011101011111010110'); -- 19 - position ----------- - 19 -(1 row) - -SELECT POSITION(B'000000000011101011111010110' IN B'000000000011101011111010110'); -- 1 - position ----------- - 1 -(1 row) - -SELECT POSITION(B'00000000011101011111010110' IN B'000000000011101011111010110'); -- 2 - position ----------- - 2 -(1 row) - -SELECT POSITION(B'0000000000011101011111010110' IN B'000000000011101011111010110'); -- 0 - position ----------- - 0 -(1 row) - --- Shifting -CREATE TABLE BIT_SHIFT_TABLE(b BIT(16)); -INSERT INTO BIT_SHIFT_TABLE VALUES (B'1101100000000000'); -INSERT INTO BIT_SHIFT_TABLE SELECT b>>1 FROM BIT_SHIFT_TABLE; -INSERT INTO BIT_SHIFT_TABLE SELECT b>>2 FROM BIT_SHIFT_TABLE; -INSERT INTO BIT_SHIFT_TABLE SELECT b>>4 FROM BIT_SHIFT_TABLE; -INSERT INTO BIT_SHIFT_TABLE SELECT b>>8 FROM BIT_SHIFT_TABLE; -SELECT POSITION(B'1101' IN b), - POSITION(B'11011' IN b), - b - FROM BIT_SHIFT_TABLE ; - position | position | b -----------+----------+------------------ - 1 | 1 | 1101100000000000 - 2 | 2 | 0110110000000000 - 3 | 3 | 0011011000000000 - 4 | 4 | 0001101100000000 - 5 | 5 | 0000110110000000 - 6 | 6 | 0000011011000000 - 7 | 7 | 0000001101100000 - 8 | 8 | 0000000110110000 - 9 | 9 | 0000000011011000 - 10 | 10 | 0000000001101100 - 11 | 11 | 0000000000110110 - 12 | 12 | 0000000000011011 - 13 | 0 | 0000000000001101 - 0 | 0 | 0000000000000110 - 0 | 0 | 0000000000000011 - 0 | 0 | 0000000000000001 -(16 rows) - -SELECT b, b >> 1 AS bsr, b << 1 AS bsl - FROM BIT_SHIFT_TABLE ; - b | bsr | bsl -------------------+------------------+------------------ - 1101100000000000 | 0110110000000000 | 1011000000000000 - 0110110000000000 | 0011011000000000 | 1101100000000000 - 0011011000000000 | 0001101100000000 | 0110110000000000 - 0001101100000000 | 0000110110000000 | 0011011000000000 - 0000110110000000 | 0000011011000000 | 0001101100000000 - 0000011011000000 | 0000001101100000 | 0000110110000000 - 0000001101100000 | 0000000110110000 | 0000011011000000 - 0000000110110000 | 0000000011011000 | 0000001101100000 - 0000000011011000 | 0000000001101100 | 0000000110110000 - 0000000001101100 | 0000000000110110 | 0000000011011000 - 0000000000110110 | 0000000000011011 | 0000000001101100 - 0000000000011011 | 0000000000001101 | 0000000000110110 - 0000000000001101 | 0000000000000110 | 0000000000011010 - 0000000000000110 | 0000000000000011 | 0000000000001100 - 0000000000000011 | 0000000000000001 | 0000000000000110 - 0000000000000001 | 0000000000000000 | 0000000000000010 -(16 rows) - -SELECT b, b >> 8 AS bsr8, b << 8 AS bsl8 - FROM BIT_SHIFT_TABLE ; - b | bsr8 | bsl8 -------------------+------------------+------------------ - 1101100000000000 | 0000000011011000 | 0000000000000000 - 0110110000000000 | 0000000001101100 | 0000000000000000 - 0011011000000000 | 0000000000110110 | 0000000000000000 - 0001101100000000 | 0000000000011011 | 0000000000000000 - 0000110110000000 | 0000000000001101 | 1000000000000000 - 0000011011000000 | 0000000000000110 | 1100000000000000 - 0000001101100000 | 0000000000000011 | 0110000000000000 - 0000000110110000 | 0000000000000001 | 1011000000000000 - 0000000011011000 | 0000000000000000 | 1101100000000000 - 0000000001101100 | 0000000000000000 | 0110110000000000 - 0000000000110110 | 0000000000000000 | 0011011000000000 - 0000000000011011 | 0000000000000000 | 0001101100000000 - 0000000000001101 | 0000000000000000 | 0000110100000000 - 0000000000000110 | 0000000000000000 | 0000011000000000 - 0000000000000011 | 0000000000000000 | 0000001100000000 - 0000000000000001 | 0000000000000000 | 0000000100000000 -(16 rows) - -SELECT b::bit(15), b::bit(15) >> 1 AS bsr, b::bit(15) << 1 AS bsl - FROM BIT_SHIFT_TABLE ; - b | bsr | bsl ------------------+-----------------+----------------- - 110110000000000 | 011011000000000 | 101100000000000 - 011011000000000 | 001101100000000 | 110110000000000 - 001101100000000 | 000110110000000 | 011011000000000 - 000110110000000 | 000011011000000 | 001101100000000 - 000011011000000 | 000001101100000 | 000110110000000 - 000001101100000 | 000000110110000 | 000011011000000 - 000000110110000 | 000000011011000 | 000001101100000 - 000000011011000 | 000000001101100 | 000000110110000 - 000000001101100 | 000000000110110 | 000000011011000 - 000000000110110 | 000000000011011 | 000000001101100 - 000000000011011 | 000000000001101 | 000000000110110 - 000000000001101 | 000000000000110 | 000000000011010 - 000000000000110 | 000000000000011 | 000000000001100 - 000000000000011 | 000000000000001 | 000000000000110 - 000000000000001 | 000000000000000 | 000000000000010 - 000000000000000 | 000000000000000 | 000000000000000 -(16 rows) - -SELECT b::bit(15), b::bit(15) >> 8 AS bsr8, b::bit(15) << 8 AS bsl8 - FROM BIT_SHIFT_TABLE ; - b | bsr8 | bsl8 ------------------+-----------------+----------------- - 110110000000000 | 000000001101100 | 000000000000000 - 011011000000000 | 000000000110110 | 000000000000000 - 001101100000000 | 000000000011011 | 000000000000000 - 000110110000000 | 000000000001101 | 000000000000000 - 000011011000000 | 000000000000110 | 100000000000000 - 000001101100000 | 000000000000011 | 110000000000000 - 000000110110000 | 000000000000001 | 011000000000000 - 000000011011000 | 000000000000000 | 101100000000000 - 000000001101100 | 000000000000000 | 110110000000000 - 000000000110110 | 000000000000000 | 011011000000000 - 000000000011011 | 000000000000000 | 001101100000000 - 000000000001101 | 000000000000000 | 000110100000000 - 000000000000110 | 000000000000000 | 000011000000000 - 000000000000011 | 000000000000000 | 000001100000000 - 000000000000001 | 000000000000000 | 000000100000000 - 000000000000000 | 000000000000000 | 000000000000000 -(16 rows) - -CREATE TABLE VARBIT_SHIFT_TABLE(v BIT VARYING(20)); -INSERT INTO VARBIT_SHIFT_TABLE VALUES (B'11011'); -INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0' AS BIT VARYING(6)) >>1 FROM VARBIT_SHIFT_TABLE; -INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00' AS BIT VARYING(8)) >>2 FROM VARBIT_SHIFT_TABLE; -INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'0000' AS BIT VARYING(12)) >>4 FROM VARBIT_SHIFT_TABLE; -INSERT INTO VARBIT_SHIFT_TABLE SELECT CAST(v || B'00000000' AS BIT VARYING(20)) >>8 FROM VARBIT_SHIFT_TABLE; -SELECT POSITION(B'1101' IN v), - POSITION(B'11011' IN v), - v - FROM VARBIT_SHIFT_TABLE ; - position | position | v -----------+----------+---------------------- - 1 | 1 | 11011 - 2 | 2 | 011011 - 3 | 3 | 0011011 - 4 | 4 | 00011011 - 5 | 5 | 000011011 - 6 | 6 | 0000011011 - 7 | 7 | 00000011011 - 8 | 8 | 000000011011 - 9 | 9 | 0000000011011 - 10 | 10 | 00000000011011 - 11 | 11 | 000000000011011 - 12 | 12 | 0000000000011011 - 13 | 13 | 00000000000011011 - 14 | 14 | 000000000000011011 - 15 | 15 | 0000000000000011011 - 16 | 16 | 00000000000000011011 -(16 rows) - -SELECT v, v >> 1 AS vsr, v << 1 AS vsl - FROM VARBIT_SHIFT_TABLE ; - v | vsr | vsl -----------------------+----------------------+---------------------- - 11011 | 01101 | 10110 - 011011 | 001101 | 110110 - 0011011 | 0001101 | 0110110 - 00011011 | 00001101 | 00110110 - 000011011 | 000001101 | 000110110 - 0000011011 | 0000001101 | 0000110110 - 00000011011 | 00000001101 | 00000110110 - 000000011011 | 000000001101 | 000000110110 - 0000000011011 | 0000000001101 | 0000000110110 - 00000000011011 | 00000000001101 | 00000000110110 - 000000000011011 | 000000000001101 | 000000000110110 - 0000000000011011 | 0000000000001101 | 0000000000110110 - 00000000000011011 | 00000000000001101 | 00000000000110110 - 000000000000011011 | 000000000000001101 | 000000000000110110 - 0000000000000011011 | 0000000000000001101 | 0000000000000110110 - 00000000000000011011 | 00000000000000001101 | 00000000000000110110 -(16 rows) - -SELECT v, v >> 8 AS vsr8, v << 8 AS vsl8 - FROM VARBIT_SHIFT_TABLE ; - v | vsr8 | vsl8 -----------------------+----------------------+---------------------- - 11011 | 00000 | 00000 - 011011 | 000000 | 000000 - 0011011 | 0000000 | 0000000 - 00011011 | 00000000 | 00000000 - 000011011 | 000000000 | 100000000 - 0000011011 | 0000000000 | 1100000000 - 00000011011 | 00000000000 | 01100000000 - 000000011011 | 000000000000 | 101100000000 - 0000000011011 | 0000000000000 | 1101100000000 - 00000000011011 | 00000000000000 | 01101100000000 - 000000000011011 | 000000000000000 | 001101100000000 - 0000000000011011 | 0000000000000000 | 0001101100000000 - 00000000000011011 | 00000000000000000 | 00001101100000000 - 000000000000011011 | 000000000000000000 | 000001101100000000 - 0000000000000011011 | 0000000000000000000 | 0000001101100000000 - 00000000000000011011 | 00000000000000000000 | 00000001101100000000 -(16 rows) - -DROP TABLE BIT_SHIFT_TABLE; -DROP TABLE VARBIT_SHIFT_TABLE; --- Get/Set bit -SELECT get_bit(B'0101011000100', 10); - get_bit ---------- - 1 -(1 row) - -SELECT set_bit(B'0101011000100100', 15, 1); - set_bit ------------------- - 0101011000100101 -(1 row) - -SELECT set_bit(B'0101011000100100', 16, 1); -- fail -ERROR: bit index 16 out of valid range (0..15) --- Overlay -SELECT overlay(B'0101011100' placing '001' from 2 for 3); - overlay ------------- - 0001011100 -(1 row) - -SELECT overlay(B'0101011100' placing '101' from 6); - overlay ------------- - 0101010100 -(1 row) - -SELECT overlay(B'0101011100' placing '001' from 11); - overlay ---------------- - 0101011100001 -(1 row) - -SELECT overlay(B'0101011100' placing '001' from 20); - overlay ---------------- - 0101011100001 -(1 row) - --- This table is intentionally left around to exercise pg_dump/pg_upgrade -CREATE TABLE bit_defaults( - b1 bit(4) DEFAULT '1001', - b2 bit(4) DEFAULT B'0101', - b3 bit varying(5) DEFAULT '1001', - b4 bit varying(5) DEFAULT B'0101' -); -\d bit_defaults - Table "public.bit_defaults" - Column | Type | Collation | Nullable | Default ---------+----------------+-----------+----------+--------------------- - b1 | bit(4) | | | '1001'::"bit" - b2 | bit(4) | | | '0101'::"bit" - b3 | bit varying(5) | | | '1001'::bit varying - b4 | bit varying(5) | | | '0101'::"bit" - -INSERT INTO bit_defaults DEFAULT VALUES; -TABLE bit_defaults; - b1 | b2 | b3 | b4 -------+------+------+------ - 1001 | 0101 | 1001 | 0101 -(1 row) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rangetypes.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/rangetypes.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rangetypes.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/rangetypes.out 2022-02-13 01:11:58.218807166 +0100 @@ -1499,62 +1499,8 @@ create type cashrange as range (subtype = money); set enable_sort = off; -- try to make it pick a hash setop implementation select '(2,5)'::cashrange except select '(5,6)'::cashrange; - cashrange ---------------- - ($2.00,$5.00) -(1 row) - -reset enable_sort; --- --- OUT/INOUT/TABLE functions --- -create function outparam_succeed(i anyrange, out r anyrange, out t text) - as $$ select $1, 'foo'::text $$ language sql; -select * from outparam_succeed(int4range(1,2)); - r | t --------+----- - [1,2) | foo -(1 row) - -create function outparam2_succeed(r anyrange, out lu anyarray, out ul anyarray) - as $$ select array[lower($1), upper($1)], array[upper($1), lower($1)] $$ - language sql; -select * from outparam2_succeed(int4range(1,11)); - lu | ul ---------+-------- - {1,11} | {11,1} -(1 row) - -create function inoutparam_succeed(out i anyelement, inout r anyrange) - as $$ select upper($1), $1 $$ language sql; -select * from inoutparam_succeed(int4range(1,2)); - i | r ----+------- - 2 | [1,2) -(1 row) - -create function table_succeed(r anyrange) - returns table(l anyelement, u anyelement) - as $$ select lower($1), upper($1) $$ - language sql; -select * from table_succeed(int4range(1,11)); - l | u ----+---- - 1 | 11 -(1 row) - --- should fail -create function outparam_fail(i anyelement, out r anyrange, out t text) - as $$ select '[1,10]', 'foo' $$ language sql; -ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. ---should fail -create function inoutparam_fail(inout i anyelement, out r anyrange) - as $$ select $1, '[1,10]' $$ language sql; -ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. ---should fail -create function table_fail(i anyelement) returns table(i anyelement, r anyrange) - as $$ select $1, '[1,10]' $$ language sql; -ERROR: cannot determine result data type -DETAIL: A result of type anyrange requires at least one input of type anyrange. +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/numerology.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/numerology.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/numerology.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/numerology.out 2022-02-13 01:11:59.768809781 +0100 @@ -76,61 +76,8 @@ INSERT INTO TEMP_GROUP SELECT 1, (- i.f1), (- f.f1) FROM INT4_TBL i, FLOAT8_TBL f; -INSERT INTO TEMP_GROUP - SELECT 2, i.f1, f.f1 - FROM INT4_TBL i, FLOAT8_TBL f; -SELECT DISTINCT f1 AS two FROM TEMP_GROUP ORDER BY 1; - two ------ - 1 - 2 -(2 rows) - -SELECT f1 AS two, max(f3) AS max_float, min(f3) as min_float - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, max_float, min_float; - two | max_float | min_float ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | -0 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - --- GROUP BY a result column name is not legal per SQL92, but we accept it --- anyway (if the name is not the name of any column exposed by FROM). -SELECT f1 AS two, max(f3) AS max_float, min(f3) AS min_float - FROM TEMP_GROUP - GROUP BY two - ORDER BY two, max_float, min_float; - two | max_float | min_float ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | -0 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - -SELECT f1 AS two, (max(f3) + 1) AS max_plus_1, (min(f3) - 1) AS min_minus_1 - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, min_minus_1; - two | max_plus_1 | min_minus_1 ------+----------------------+----------------------- - 1 | 1.2345678901234e+200 | -1 - 2 | 1 | -1.2345678901234e+200 -(2 rows) - -SELECT f1 AS two, - max(f2) + min(f2) AS max_plus_min, - min(f3) - 1 AS min_minus_1 - FROM TEMP_GROUP - GROUP BY f1 - ORDER BY two, min_minus_1; - two | max_plus_min | min_minus_1 ------+--------------+----------------------- - 1 | 0 | -1 - 2 | 0 | -1.2345678901234e+200 -(2 rows) - -DROP TABLE TEMP_INT2; -DROP TABLE TEMP_INT4; -DROP TABLE TEMP_FLOAT; -DROP TABLE TEMP_GROUP; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/point.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/point.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/point.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/point.out 2022-02-13 01:11:59.792143154 +0100 @@ -158,266 +158,8 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dist FROM POINT_TBL p1, POINT_TBL p2 ORDER BY dist, p1.f1[0], p2.f1[0]; - thirtysix | point1 | point2 | dist ------------+-------------------+-------------------+---------------------- - | (-10,0) | (-10,0) | 0 - | (-5,-12) | (-5,-12) | 0 - | (-3,4) | (-3,4) | 0 - | (0,0) | (0,0) | 0 - | (1e-300,-1e-300) | (1e-300,-1e-300) | 0 - | (5.1,34.5) | (5.1,34.5) | 0 - | (10,10) | (10,10) | 0 - | (0,0) | (1e-300,-1e-300) | 1.4142135623731e-300 - | (1e-300,-1e-300) | (0,0) | 1.4142135623731e-300 - | (-3,4) | (0,0) | 5 - | (-3,4) | (1e-300,-1e-300) | 5 - | (0,0) | (-3,4) | 5 - | (1e-300,-1e-300) | (-3,4) | 5 - | (-10,0) | (-3,4) | 8.06225774829855 - | (-3,4) | (-10,0) | 8.06225774829855 - | (-10,0) | (0,0) | 10 - | (-10,0) | (1e-300,-1e-300) | 10 - | (0,0) | (-10,0) | 10 - | (1e-300,-1e-300) | (-10,0) | 10 - | (-10,0) | (-5,-12) | 13 - | (-5,-12) | (-10,0) | 13 - | (-5,-12) | (0,0) | 13 - | (-5,-12) | (1e-300,-1e-300) | 13 - | (0,0) | (-5,-12) | 13 - | (1e-300,-1e-300) | (-5,-12) | 13 - | (0,0) | (10,10) | 14.142135623731 - | (1e-300,-1e-300) | (10,10) | 14.142135623731 - | (10,10) | (0,0) | 14.142135623731 - | (10,10) | (1e-300,-1e-300) | 14.142135623731 - | (-3,4) | (10,10) | 14.3178210632764 - | (10,10) | (-3,4) | 14.3178210632764 - | (-5,-12) | (-3,4) | 16.1245154965971 - | (-3,4) | (-5,-12) | 16.1245154965971 - | (-10,0) | (10,10) | 22.3606797749979 - | (10,10) | (-10,0) | 22.3606797749979 - | (5.1,34.5) | (10,10) | 24.9851956166046 - | (10,10) | (5.1,34.5) | 24.9851956166046 - | (-5,-12) | (10,10) | 26.6270539113887 - | (10,10) | (-5,-12) | 26.6270539113887 - | (-3,4) | (5.1,34.5) | 31.5572495632937 - | (5.1,34.5) | (-3,4) | 31.5572495632937 - | (0,0) | (5.1,34.5) | 34.8749193547455 - | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 - | (5.1,34.5) | (0,0) | 34.8749193547455 - | (5.1,34.5) | (1e-300,-1e-300) | 34.8749193547455 - | (-10,0) | (5.1,34.5) | 37.6597928831267 - | (5.1,34.5) | (-10,0) | 37.6597928831267 - | (-5,-12) | (5.1,34.5) | 47.5842410888311 - | (5.1,34.5) | (-5,-12) | 47.5842410888311 - | (-10,0) | (1e+300,Infinity) | Infinity - | (-5,-12) | (1e+300,Infinity) | Infinity - | (-3,4) | (1e+300,Infinity) | Infinity - | (0,0) | (1e+300,Infinity) | Infinity - | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity - | (5.1,34.5) | (1e+300,Infinity) | Infinity - | (10,10) | (1e+300,Infinity) | Infinity - | (1e+300,Infinity) | (-10,0) | Infinity - | (1e+300,Infinity) | (-5,-12) | Infinity - | (1e+300,Infinity) | (-3,4) | Infinity - | (1e+300,Infinity) | (0,0) | Infinity - | (1e+300,Infinity) | (1e-300,-1e-300) | Infinity - | (1e+300,Infinity) | (5.1,34.5) | Infinity - | (1e+300,Infinity) | (10,10) | Infinity - | (-10,0) | (NaN,NaN) | NaN - | (-5,-12) | (NaN,NaN) | NaN - | (-3,4) | (NaN,NaN) | NaN - | (0,0) | (NaN,NaN) | NaN - | (1e-300,-1e-300) | (NaN,NaN) | NaN - | (5.1,34.5) | (NaN,NaN) | NaN - | (10,10) | (NaN,NaN) | NaN - | (1e+300,Infinity) | (1e+300,Infinity) | NaN - | (1e+300,Infinity) | (NaN,NaN) | NaN - | (NaN,NaN) | (-10,0) | NaN - | (NaN,NaN) | (-5,-12) | NaN - | (NaN,NaN) | (-3,4) | NaN - | (NaN,NaN) | (0,0) | NaN - | (NaN,NaN) | (1e-300,-1e-300) | NaN - | (NaN,NaN) | (5.1,34.5) | NaN - | (NaN,NaN) | (10,10) | NaN - | (NaN,NaN) | (1e+300,Infinity) | NaN - | (NaN,NaN) | (NaN,NaN) | NaN -(81 rows) - -SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 - FROM POINT_TBL p1, POINT_TBL p2 - WHERE (p1.f1 <-> p2.f1) > 3; - thirty | point1 | point2 ---------+-------------------+------------------- - | (0,0) | (-10,0) - | (0,0) | (-3,4) - | (0,0) | (5.1,34.5) - | (0,0) | (-5,-12) - | (0,0) | (1e+300,Infinity) - | (0,0) | (NaN,NaN) - | (0,0) | (10,10) - | (-10,0) | (0,0) - | (-10,0) | (-3,4) - | (-10,0) | (5.1,34.5) - | (-10,0) | (-5,-12) - | (-10,0) | (1e-300,-1e-300) - | (-10,0) | (1e+300,Infinity) - | (-10,0) | (NaN,NaN) - | (-10,0) | (10,10) - | (-3,4) | (0,0) - | (-3,4) | (-10,0) - | (-3,4) | (5.1,34.5) - | (-3,4) | (-5,-12) - | (-3,4) | (1e-300,-1e-300) - | (-3,4) | (1e+300,Infinity) - | (-3,4) | (NaN,NaN) - | (-3,4) | (10,10) - | (5.1,34.5) | (0,0) - | (5.1,34.5) | (-10,0) - | (5.1,34.5) | (-3,4) - | (5.1,34.5) | (-5,-12) - | (5.1,34.5) | (1e-300,-1e-300) - | (5.1,34.5) | (1e+300,Infinity) - | (5.1,34.5) | (NaN,NaN) - | (5.1,34.5) | (10,10) - | (-5,-12) | (0,0) - | (-5,-12) | (-10,0) - | (-5,-12) | (-3,4) - | (-5,-12) | (5.1,34.5) - | (-5,-12) | (1e-300,-1e-300) - | (-5,-12) | (1e+300,Infinity) - | (-5,-12) | (NaN,NaN) - | (-5,-12) | (10,10) - | (1e-300,-1e-300) | (-10,0) - | (1e-300,-1e-300) | (-3,4) - | (1e-300,-1e-300) | (5.1,34.5) - | (1e-300,-1e-300) | (-5,-12) - | (1e-300,-1e-300) | (1e+300,Infinity) - | (1e-300,-1e-300) | (NaN,NaN) - | (1e-300,-1e-300) | (10,10) - | (1e+300,Infinity) | (0,0) - | (1e+300,Infinity) | (-10,0) - | (1e+300,Infinity) | (-3,4) - | (1e+300,Infinity) | (5.1,34.5) - | (1e+300,Infinity) | (-5,-12) - | (1e+300,Infinity) | (1e-300,-1e-300) - | (1e+300,Infinity) | (1e+300,Infinity) - | (1e+300,Infinity) | (NaN,NaN) - | (1e+300,Infinity) | (10,10) - | (NaN,NaN) | (0,0) - | (NaN,NaN) | (-10,0) - | (NaN,NaN) | (-3,4) - | (NaN,NaN) | (5.1,34.5) - | (NaN,NaN) | (-5,-12) - | (NaN,NaN) | (1e-300,-1e-300) - | (NaN,NaN) | (1e+300,Infinity) - | (NaN,NaN) | (NaN,NaN) - | (NaN,NaN) | (10,10) - | (10,10) | (0,0) - | (10,10) | (-10,0) - | (10,10) | (-3,4) - | (10,10) | (5.1,34.5) - | (10,10) | (-5,-12) - | (10,10) | (1e-300,-1e-300) - | (10,10) | (1e+300,Infinity) - | (10,10) | (NaN,NaN) -(72 rows) - --- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 -SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance - FROM POINT_TBL p1, POINT_TBL p2 - WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 - ORDER BY distance, p1.f1[0], p2.f1[0]; - fifteen | point1 | point2 | distance ----------+------------------+-------------------+------------------ - | (-3,4) | (0,0) | 5 - | (-3,4) | (1e-300,-1e-300) | 5 - | (-10,0) | (-3,4) | 8.06225774829855 - | (-10,0) | (0,0) | 10 - | (-10,0) | (1e-300,-1e-300) | 10 - | (-10,0) | (-5,-12) | 13 - | (-5,-12) | (0,0) | 13 - | (-5,-12) | (1e-300,-1e-300) | 13 - | (0,0) | (10,10) | 14.142135623731 - | (1e-300,-1e-300) | (10,10) | 14.142135623731 - | (-3,4) | (10,10) | 14.3178210632764 - | (-5,-12) | (-3,4) | 16.1245154965971 - | (-10,0) | (10,10) | 22.3606797749979 - | (5.1,34.5) | (10,10) | 24.9851956166046 - | (-5,-12) | (10,10) | 26.6270539113887 - | (-3,4) | (5.1,34.5) | 31.5572495632937 - | (0,0) | (5.1,34.5) | 34.8749193547455 - | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 - | (-10,0) | (5.1,34.5) | 37.6597928831267 - | (-5,-12) | (5.1,34.5) | 47.5842410888311 - | (-10,0) | (1e+300,Infinity) | Infinity - | (-5,-12) | (1e+300,Infinity) | Infinity - | (-3,4) | (1e+300,Infinity) | Infinity - | (0,0) | (1e+300,Infinity) | Infinity - | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity - | (5.1,34.5) | (1e+300,Infinity) | Infinity - | (10,10) | (1e+300,Infinity) | Infinity -(27 rows) - --- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 -SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance - FROM POINT_TBL p1, POINT_TBL p2 - WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1 - ORDER BY distance; - three | point1 | point2 | distance --------+------------+------------------+------------------ - | (-3,4) | (0,0) | 5 - | (-3,4) | (1e-300,-1e-300) | 5 - | (-10,0) | (-5,-12) | 13 - | (5.1,34.5) | (10,10) | 24.9851956166046 -(4 rows) - --- Test that GiST indexes provide same behavior as sequential scan -CREATE TEMP TABLE point_gist_tbl(f1 point); -INSERT INTO point_gist_tbl SELECT '(0,0)' FROM generate_series(0,1000); -CREATE INDEX point_gist_tbl_index ON point_gist_tbl USING gist (f1); -INSERT INTO point_gist_tbl VALUES ('(0.0000009,0.0000009)'); -SET enable_seqscan TO true; -SET enable_indexscan TO false; -SET enable_bitmapscan TO false; -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; - count -------- - 1002 -(1 row) - -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; - count -------- - 1 -(1 row) - -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; - count -------- - 1 -(1 row) - -SET enable_seqscan TO false; -SET enable_indexscan TO true; -SET enable_bitmapscan TO true; -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000009,0.0000009)'::point; - count -------- - 1002 -(1 row) - -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 <@ '(0.0000009,0.0000009),(0.0000009,0.0000009)'::box; - count -------- - 1 -(1 row) - -SELECT COUNT(*) FROM point_gist_tbl WHERE f1 ~= '(0.0000018,0.0000018)'::point; - count -------- - 1 -(1 row) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/box.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/box.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/box.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/box.out 2022-02-13 01:12:00.642144589 +0100 @@ -609,33 +609,8 @@ ON seq.n = idx.n AND seq.id = idx.id AND (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) WHERE seq.id IS NULL OR idx.id IS NULL; - n | dist | id | n | dist | id ----+------+----+---+------+---- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id -FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; - QUERY PLAN ---------------------------------------------------------- - WindowAgg - -> Index Scan using quad_box_tbl_idx on quad_box_tbl - Index Cond: (b <@ '(500,600),(200,300)'::box) - Order By: (b <-> '(123,456)'::point) -(4 rows) - -CREATE TEMP TABLE quad_box_tbl_ord_idx2 AS -SELECT rank() OVER (ORDER BY b <-> point '123,456') n, b <-> point '123,456' dist, id -FROM quad_box_tbl WHERE b <@ box '((200,300),(500,600))'; -SELECT * -FROM quad_box_tbl_ord_seq2 seq FULL JOIN quad_box_tbl_ord_idx2 idx - ON seq.n = idx.n AND seq.id = idx.id AND - (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) -WHERE seq.id IS NULL OR idx.id IS NULL; - n | dist | id | n | dist | id ----+------+----+---+------+---- -(0 rows) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/polygon.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/polygon.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/polygon.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/polygon.out 2022-02-13 01:12:01.135478755 +0100 @@ -299,10 +299,8 @@ ON seq.n = idx.n AND seq.id = idx.id AND (seq.dist = idx.dist OR seq.dist IS NULL AND idx.dist IS NULL) WHERE seq.id IS NULL OR idx.id IS NULL; - n | dist | id | n | dist | id ----+------+----+---+------+---- -(0 rows) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/interval.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/interval.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/interval.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/interval.out 2022-02-13 01:11:59.755476426 +0100 @@ -158,775 +158,8 @@ FROM INTERVAL_TBL r1, INTERVAL_TBL r2 WHERE r1.f1 > r2.f1 ORDER BY r1.f1, r2.f1; - fortyfive | f1 | f1 ------------+-----------------+----------------- - | 00:01:00 | -00:00:14 - | 05:00:00 | -00:00:14 - | 05:00:00 | 00:01:00 - | 1 day 02:03:04 | -00:00:14 - | 1 day 02:03:04 | 00:01:00 - | 1 day 02:03:04 | 05:00:00 - | 10 days | -00:00:14 - | 10 days | 00:01:00 - | 10 days | 05:00:00 - | 10 days | 1 day 02:03:04 - | 3 mons | -00:00:14 - | 3 mons | 00:01:00 - | 3 mons | 05:00:00 - | 3 mons | 1 day 02:03:04 - | 3 mons | 10 days - | 5 mons | -00:00:14 - | 5 mons | 00:01:00 - | 5 mons | 05:00:00 - | 5 mons | 1 day 02:03:04 - | 5 mons | 10 days - | 5 mons | 3 mons - | 5 mons 12:00:00 | -00:00:14 - | 5 mons 12:00:00 | 00:01:00 - | 5 mons 12:00:00 | 05:00:00 - | 5 mons 12:00:00 | 1 day 02:03:04 - | 5 mons 12:00:00 | 10 days - | 5 mons 12:00:00 | 3 mons - | 5 mons 12:00:00 | 5 mons - | 6 years | -00:00:14 - | 6 years | 00:01:00 - | 6 years | 05:00:00 - | 6 years | 1 day 02:03:04 - | 6 years | 10 days - | 6 years | 3 mons - | 6 years | 5 mons - | 6 years | 5 mons 12:00:00 - | 34 years | -00:00:14 - | 34 years | 00:01:00 - | 34 years | 05:00:00 - | 34 years | 1 day 02:03:04 - | 34 years | 10 days - | 34 years | 3 mons - | 34 years | 5 mons - | 34 years | 5 mons 12:00:00 - | 34 years | 6 years -(45 rows) - --- Test intervals that are large enough to overflow 64 bits in comparisons -CREATE TEMP TABLE INTERVAL_TBL_OF (f1 interval); -INSERT INTO INTERVAL_TBL_OF (f1) VALUES - ('2147483647 days 2147483647 months'), - ('2147483647 days -2147483648 months'), - ('1 year'), - ('-2147483648 days 2147483647 months'), - ('-2147483648 days -2147483648 months'); --- these should fail as out-of-range -INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days'); -ERROR: interval field value out of range: "2147483648 days" -LINE 1: INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483648 days'); - ^ -INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days'); -ERROR: interval field value out of range: "-2147483649 days" -LINE 1: INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483649 days')... - ^ -INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years'); -ERROR: interval out of range -LINE 1: INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('2147483647 years')... - ^ -INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years'); -ERROR: interval out of range -LINE 1: INSERT INTO INTERVAL_TBL_OF (f1) VALUES ('-2147483648 years'... - ^ --- Test edge-case overflow detection in interval multiplication -select extract(epoch from '256 microseconds'::interval * (2^55)::float8); -ERROR: interval out of range -SELECT r1.*, r2.* - FROM INTERVAL_TBL_OF r1, INTERVAL_TBL_OF r2 - WHERE r1.f1 > r2.f1 - ORDER BY r1.f1, r2.f1; - f1 | f1 --------------------------------------------+------------------------------------------- - -178956970 years -8 mons +2147483647 days | -178956970 years -8 mons -2147483648 days - 1 year | -178956970 years -8 mons -2147483648 days - 1 year | -178956970 years -8 mons +2147483647 days - 178956970 years 7 mons -2147483648 days | -178956970 years -8 mons -2147483648 days - 178956970 years 7 mons -2147483648 days | -178956970 years -8 mons +2147483647 days - 178956970 years 7 mons -2147483648 days | 1 year - 178956970 years 7 mons 2147483647 days | -178956970 years -8 mons -2147483648 days - 178956970 years 7 mons 2147483647 days | -178956970 years -8 mons +2147483647 days - 178956970 years 7 mons 2147483647 days | 1 year - 178956970 years 7 mons 2147483647 days | 178956970 years 7 mons -2147483648 days -(10 rows) - -CREATE INDEX ON INTERVAL_TBL_OF USING btree (f1); -SET enable_seqscan TO false; -EXPLAIN (COSTS OFF) -SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1; - QUERY PLAN --------------------------------------------------------------------- - Index Only Scan using interval_tbl_of_f1_idx on interval_tbl_of r1 -(1 row) - -SELECT f1 FROM INTERVAL_TBL_OF r1 ORDER BY f1; - f1 -------------------------------------------- - -178956970 years -8 mons -2147483648 days - -178956970 years -8 mons +2147483647 days - 1 year - 178956970 years 7 mons -2147483648 days - 178956970 years 7 mons 2147483647 days -(5 rows) - -RESET enable_seqscan; -DROP TABLE INTERVAL_TBL_OF; --- Test multiplication and division with intervals. --- Floating point arithmetic rounding errors can lead to unexpected results, --- though the code attempts to do the right thing and round up to days and --- minutes to avoid results such as '3 days 24:00 hours' or '14:20:60'. --- Note that it is expected for some day components to be greater than 29 and --- some time components be greater than 23:59:59 due to how intervals are --- stored internally. -CREATE TABLE INTERVAL_MULDIV_TBL (span interval); -COPY INTERVAL_MULDIV_TBL FROM STDIN; -SELECT span * 0.3 AS product -FROM INTERVAL_MULDIV_TBL; - product ------------------------------------- - 1 year 12 days 122:24:00 - -1 years -12 days +93:36:00 - -3 days -14:24:00 - 2 mons 13 days 01:22:28.8 - -10 mons +120 days 37:28:21.6567 - 1 mon 6 days - 4 mons 6 days - 24 years 11 mons 320 days 16:48:00 -(8 rows) - -SELECT span * 8.2 AS product -FROM INTERVAL_MULDIV_TBL; - product ---------------------------------------------- - 28 years 104 days 2961:36:00 - -28 years -104 days +2942:24:00 - -98 days -09:36:00 - 6 years 1 mon -197 days +93:34:27.2 - -24 years -7 mons +3946 days 640:15:11.9498 - 2 years 8 mons 24 days - 9 years 6 mons 24 days - 682 years 7 mons 8215 days 19:12:00 -(8 rows) - -SELECT span / 10 AS quotient -FROM INTERVAL_MULDIV_TBL; - quotient ----------------------------------- - 4 mons 4 days 40:48:00 - -4 mons -4 days +31:12:00 - -1 days -04:48:00 - 25 days -15:32:30.4 - -3 mons +30 days 12:29:27.2189 - 12 days - 1 mon 12 days - 8 years 3 mons 126 days 21:36:00 -(8 rows) - -SELECT span / 100 AS quotient -FROM INTERVAL_MULDIV_TBL; - quotient -------------------------- - 12 days 13:40:48 - -12 days -06:28:48 - -02:52:48 - 2 days 10:26:44.96 - -6 days +01:14:56.72189 - 1 day 04:48:00 - 4 days 04:48:00 - 9 mons 39 days 16:33:36 -(8 rows) - -DROP TABLE INTERVAL_MULDIV_TBL; -SET DATESTYLE = 'postgres'; -SET IntervalStyle to postgres_verbose; -SELECT '' AS ten, * FROM INTERVAL_TBL; - ten | f1 ------+------------------------------- - | @ 1 min - | @ 5 hours - | @ 10 days - | @ 34 years - | @ 3 mons - | @ 14 secs ago - | @ 1 day 2 hours 3 mins 4 secs - | @ 6 years - | @ 5 mons - | @ 5 mons 12 hours -(10 rows) - --- test avg(interval), which is somewhat fragile since people have been --- known to change the allowed input syntax for type interval without --- updating pg_aggregate.agginitval -select avg(f1) from interval_tbl; - avg -------------------------------------------------- - @ 4 years 1 mon 10 days 4 hours 18 mins 23 secs -(1 row) - --- test long interval input -select '4 millenniums 5 centuries 4 decades 1 year 4 months 4 days 17 minutes 31 seconds'::interval; - interval --------------------------------------------- - @ 4541 years 4 mons 4 days 17 mins 31 secs -(1 row) - --- test long interval output --- Note: the actual maximum length of the interval output is longer, --- but we need the test to work for both integer and floating-point --- timestamps. -select '100000000y 10mon -1000000000d -100000h -10min -10.000001s ago'::interval; - interval ---------------------------------------------------------------------------------------- - @ 100000000 years 10 mons -1000000000 days -100000 hours -10 mins -10.000001 secs ago -(1 row) - --- test justify_hours() and justify_days() -SELECT justify_hours(interval '6 months 3 days 52 hours 3 minutes 2 seconds') as "6 mons 5 days 4 hours 3 mins 2 seconds"; - 6 mons 5 days 4 hours 3 mins 2 seconds ----------------------------------------- - @ 6 mons 5 days 4 hours 3 mins 2 secs -(1 row) - -SELECT justify_days(interval '6 months 36 days 5 hours 4 minutes 3 seconds') as "7 mons 6 days 5 hours 4 mins 3 seconds"; - 7 mons 6 days 5 hours 4 mins 3 seconds ----------------------------------------- - @ 7 mons 6 days 5 hours 4 mins 3 secs -(1 row) - --- test justify_interval() -SELECT justify_interval(interval '1 month -1 hour') as "1 month -1 hour"; - 1 month -1 hour --------------------- - @ 29 days 23 hours -(1 row) - --- test fractional second input, and detection of duplicate units -SET DATESTYLE = 'ISO'; -SET IntervalStyle TO postgres; -SELECT '1 millisecond'::interval, '1 microsecond'::interval, - '500 seconds 99 milliseconds 51 microseconds'::interval; - interval | interval | interval ---------------+-----------------+----------------- - 00:00:00.001 | 00:00:00.000001 | 00:08:20.099051 -(1 row) - -SELECT '3 days 5 milliseconds'::interval; - interval ---------------------- - 3 days 00:00:00.005 -(1 row) - -SELECT '1 second 2 seconds'::interval; -- error -ERROR: invalid input syntax for type interval: "1 second 2 seconds" -LINE 1: SELECT '1 second 2 seconds'::interval; - ^ -SELECT '10 milliseconds 20 milliseconds'::interval; -- error -ERROR: invalid input syntax for type interval: "10 milliseconds 20 milliseconds" -LINE 1: SELECT '10 milliseconds 20 milliseconds'::interval; - ^ -SELECT '5.5 seconds 3 milliseconds'::interval; -- error -ERROR: invalid input syntax for type interval: "5.5 seconds 3 milliseconds" -LINE 1: SELECT '5.5 seconds 3 milliseconds'::interval; - ^ -SELECT '1:20:05 5 microseconds'::interval; -- error -ERROR: invalid input syntax for type interval: "1:20:05 5 microseconds" -LINE 1: SELECT '1:20:05 5 microseconds'::interval; - ^ -SELECT '1 day 1 day'::interval; -- error -ERROR: invalid input syntax for type interval: "1 day 1 day" -LINE 1: SELECT '1 day 1 day'::interval; - ^ -SELECT interval '1-2'; -- SQL year-month literal - interval ---------------- - 1 year 2 mons -(1 row) - -SELECT interval '999' second; -- oversize leading field is ok - interval ----------- - 00:16:39 -(1 row) - -SELECT interval '999' minute; - interval ----------- - 16:39:00 -(1 row) - -SELECT interval '999' hour; - interval ------------ - 999:00:00 -(1 row) - -SELECT interval '999' day; - interval ----------- - 999 days -(1 row) - -SELECT interval '999' month; - interval ------------------ - 83 years 3 mons -(1 row) - --- test SQL-spec syntaxes for restricted field sets -SELECT interval '1' year; - interval ----------- - 1 year -(1 row) - -SELECT interval '2' month; - interval ----------- - 2 mons -(1 row) - -SELECT interval '3' day; - interval ----------- - 3 days -(1 row) - -SELECT interval '4' hour; - interval ----------- - 04:00:00 -(1 row) - -SELECT interval '5' minute; - interval ----------- - 00:05:00 -(1 row) - -SELECT interval '6' second; - interval ----------- - 00:00:06 -(1 row) - -SELECT interval '1' year to month; - interval ----------- - 1 mon -(1 row) - -SELECT interval '1-2' year to month; - interval ---------------- - 1 year 2 mons -(1 row) - -SELECT interval '1 2' day to hour; - interval ----------------- - 1 day 02:00:00 -(1 row) - -SELECT interval '1 2:03' day to hour; - interval ----------------- - 1 day 02:00:00 -(1 row) - -SELECT interval '1 2:03:04' day to hour; - interval ----------------- - 1 day 02:00:00 -(1 row) - -SELECT interval '1 2' day to minute; -ERROR: invalid input syntax for type interval: "1 2" -LINE 1: SELECT interval '1 2' day to minute; - ^ -SELECT interval '1 2:03' day to minute; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2:03:04' day to minute; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2' day to second; -ERROR: invalid input syntax for type interval: "1 2" -LINE 1: SELECT interval '1 2' day to second; - ^ -SELECT interval '1 2:03' day to second; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2:03:04' day to second; - interval ----------------- - 1 day 02:03:04 -(1 row) - -SELECT interval '1 2' hour to minute; -ERROR: invalid input syntax for type interval: "1 2" -LINE 1: SELECT interval '1 2' hour to minute; - ^ -SELECT interval '1 2:03' hour to minute; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2:03:04' hour to minute; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2' hour to second; -ERROR: invalid input syntax for type interval: "1 2" -LINE 1: SELECT interval '1 2' hour to second; - ^ -SELECT interval '1 2:03' hour to second; - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2:03:04' hour to second; - interval ----------------- - 1 day 02:03:04 -(1 row) - -SELECT interval '1 2' minute to second; -ERROR: invalid input syntax for type interval: "1 2" -LINE 1: SELECT interval '1 2' minute to second; - ^ -SELECT interval '1 2:03' minute to second; - interval ----------------- - 1 day 00:02:03 -(1 row) - -SELECT interval '1 2:03:04' minute to second; - interval ----------------- - 1 day 02:03:04 -(1 row) - -SELECT interval '1 +2:03' minute to second; - interval ----------------- - 1 day 00:02:03 -(1 row) - -SELECT interval '1 +2:03:04' minute to second; - interval ----------------- - 1 day 02:03:04 -(1 row) - -SELECT interval '1 -2:03' minute to second; - interval ------------------ - 1 day -00:02:03 -(1 row) - -SELECT interval '1 -2:03:04' minute to second; - interval ------------------ - 1 day -02:03:04 -(1 row) - -SELECT interval '123 11' day to hour; -- ok - interval -------------------- - 123 days 11:00:00 -(1 row) - -SELECT interval '123 11' day; -- not ok -ERROR: invalid input syntax for type interval: "123 11" -LINE 1: SELECT interval '123 11' day; - ^ -SELECT interval '123 11'; -- not ok, too ambiguous -ERROR: invalid input syntax for type interval: "123 11" -LINE 1: SELECT interval '123 11'; - ^ -SELECT interval '123 2:03 -2:04'; -- not ok, redundant hh:mm fields -ERROR: invalid input syntax for type interval: "123 2:03 -2:04" -LINE 1: SELECT interval '123 2:03 -2:04'; - ^ --- test syntaxes for restricted precision -SELECT interval(0) '1 day 01:23:45.6789'; - interval ----------------- - 1 day 01:23:46 -(1 row) - -SELECT interval(2) '1 day 01:23:45.6789'; - interval -------------------- - 1 day 01:23:45.68 -(1 row) - -SELECT interval '12:34.5678' minute to second(2); -- per SQL spec - interval -------------- - 00:12:34.57 -(1 row) - -SELECT interval '1.234' second; - interval --------------- - 00:00:01.234 -(1 row) - -SELECT interval '1.234' second(2); - interval -------------- - 00:00:01.23 -(1 row) - -SELECT interval '1 2.345' day to second(2); -ERROR: invalid input syntax for type interval: "1 2.345" -LINE 1: SELECT interval '1 2.345' day to second(2); - ^ -SELECT interval '1 2:03' day to second(2); - interval ----------------- - 1 day 02:03:00 -(1 row) - -SELECT interval '1 2:03.4567' day to second(2); - interval -------------------- - 1 day 00:02:03.46 -(1 row) - -SELECT interval '1 2:03:04.5678' day to second(2); - interval -------------------- - 1 day 02:03:04.57 -(1 row) - -SELECT interval '1 2.345' hour to second(2); -ERROR: invalid input syntax for type interval: "1 2.345" -LINE 1: SELECT interval '1 2.345' hour to second(2); - ^ -SELECT interval '1 2:03.45678' hour to second(2); - interval -------------------- - 1 day 00:02:03.46 -(1 row) - -SELECT interval '1 2:03:04.5678' hour to second(2); - interval -------------------- - 1 day 02:03:04.57 -(1 row) - -SELECT interval '1 2.3456' minute to second(2); -ERROR: invalid input syntax for type interval: "1 2.3456" -LINE 1: SELECT interval '1 2.3456' minute to second(2); - ^ -SELECT interval '1 2:03.5678' minute to second(2); - interval -------------------- - 1 day 00:02:03.57 -(1 row) - -SELECT interval '1 2:03:04.5678' minute to second(2); - interval -------------------- - 1 day 02:03:04.57 -(1 row) - --- test casting to restricted precision (bug #14479) -SELECT f1, f1::INTERVAL DAY TO MINUTE AS "minutes", - (f1 + INTERVAL '1 month')::INTERVAL MONTH::INTERVAL YEAR AS "years" - FROM interval_tbl; - f1 | minutes | years ------------------+-----------------+---------- - 00:01:00 | 00:01:00 | 00:00:00 - 05:00:00 | 05:00:00 | 00:00:00 - 10 days | 10 days | 00:00:00 - 34 years | 34 years | 34 years - 3 mons | 3 mons | 00:00:00 - -00:00:14 | 00:00:00 | 00:00:00 - 1 day 02:03:04 | 1 day 02:03:00 | 00:00:00 - 6 years | 6 years | 6 years - 5 mons | 5 mons | 00:00:00 - 5 mons 12:00:00 | 5 mons 12:00:00 | 00:00:00 -(10 rows) - --- test inputting and outputting SQL standard interval literals -SET IntervalStyle TO sql_standard; -SELECT interval '0' AS "zero", - interval '1-2' year to month AS "year-month", - interval '1 2:03:04' day to second AS "day-time", - - interval '1-2' AS "negative year-month", - - interval '1 2:03:04' AS "negative day-time"; - zero | year-month | day-time | negative year-month | negative day-time -------+------------+-----------+---------------------+------------------- - 0 | 1-2 | 1 2:03:04 | -1-2 | -1 2:03:04 -(1 row) - --- test input of some not-quite-standard interval values in the sql style -SET IntervalStyle TO postgres; -SELECT interval '+1 -1:00:00', - interval '-1 +1:00:00', - interval '+1-2 -3 +4:05:06.789', - interval '-1-2 +3 -4:05:06.789'; - interval | interval | interval | interval ------------------+-------------------+-------------------------------------+---------------------------------------- - 1 day -01:00:00 | -1 days +01:00:00 | 1 year 2 mons -3 days +04:05:06.789 | -1 years -2 mons +3 days -04:05:06.789 -(1 row) - --- test output of couple non-standard interval values in the sql style -SET IntervalStyle TO sql_standard; -SELECT interval '1 day -1 hours', - interval '-1 days +1 hours', - interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds', - - interval '1 years 2 months -3 days 4 hours 5 minutes 6.789 seconds'; - interval | interval | interval | ?column? -------------------+------------------+----------------------+---------------------- - +0-0 +1 -1:00:00 | +0-0 -1 +1:00:00 | +1-2 -3 +4:05:06.789 | -1-2 +3 -4:05:06.789 -(1 row) - --- test outputting iso8601 intervals -SET IntervalStyle to iso_8601; -select interval '0' AS "zero", - interval '1-2' AS "a year 2 months", - interval '1 2:03:04' AS "a bit over a day", - interval '2:03:04.45679' AS "a bit over 2 hours", - (interval '1-2' + interval '3 4:05:06.7') AS "all fields", - (interval '1-2' - interval '3 4:05:06.7') AS "mixed sign", - (- interval '1-2' + interval '3 4:05:06.7') AS "negative"; - zero | a year 2 months | a bit over a day | a bit over 2 hours | all fields | mixed sign | negative -------+-----------------+------------------+--------------------+------------------+----------------------+-------------------- - PT0S | P1Y2M | P1DT2H3M4S | PT2H3M4.45679S | P1Y2M3DT4H5M6.7S | P1Y2M-3DT-4H-5M-6.7S | P-1Y-2M3DT4H5M6.7S -(1 row) - --- test inputting ISO 8601 4.4.2.1 "Format With Time Unit Designators" -SET IntervalStyle to sql_standard; -select interval 'P0Y' AS "zero", - interval 'P1Y2M' AS "a year 2 months", - interval 'P1W' AS "a week", - interval 'P1DT2H3M4S' AS "a bit over a day", - interval 'P1Y2M3DT4H5M6.7S' AS "all fields", - interval 'P-1Y-2M-3DT-4H-5M-6.7S' AS "negative", - interval 'PT-0.1S' AS "fractional second"; - zero | a year 2 months | a week | a bit over a day | all fields | negative | fractional second -------+-----------------+-----------+------------------+--------------------+--------------------+------------------- - 0 | 1-2 | 7 0:00:00 | 1 2:03:04 | +1-2 +3 +4:05:06.7 | -1-2 -3 -4:05:06.7 | -0:00:00.1 -(1 row) - --- test inputting ISO 8601 4.4.2.2 "Alternative Format" -SET IntervalStyle to postgres; -select interval 'P00021015T103020' AS "ISO8601 Basic Format", - interval 'P0002-10-15T10:30:20' AS "ISO8601 Extended Format"; - ISO8601 Basic Format | ISO8601 Extended Format -----------------------------------+---------------------------------- - 2 years 10 mons 15 days 10:30:20 | 2 years 10 mons 15 days 10:30:20 -(1 row) - --- Make sure optional ISO8601 alternative format fields are optional. -select interval 'P0002' AS "year only", - interval 'P0002-10' AS "year month", - interval 'P0002-10-15' AS "year month day", - interval 'P0002T1S' AS "year only plus time", - interval 'P0002-10T1S' AS "year month plus time", - interval 'P0002-10-15T1S' AS "year month day plus time", - interval 'PT10' AS "hour only", - interval 'PT10:30' AS "hour minute"; - year only | year month | year month day | year only plus time | year month plus time | year month day plus time | hour only | hour minute ------------+-----------------+-------------------------+---------------------+--------------------------+----------------------------------+-----------+------------- - 2 years | 2 years 10 mons | 2 years 10 mons 15 days | 2 years 00:00:01 | 2 years 10 mons 00:00:01 | 2 years 10 mons 15 days 00:00:01 | 10:00:00 | 10:30:00 -(1 row) - --- test a couple rounding cases that changed since 8.3 w/ HAVE_INT64_TIMESTAMP. -SET IntervalStyle to postgres_verbose; -select interval '-10 mons -3 days +03:55:06.70'; - interval --------------------------------------------------- - @ 10 mons 3 days -3 hours -55 mins -6.7 secs ago -(1 row) - -select interval '1 year 2 mons 3 days 04:05:06.699999'; - interval ------------------------------------------------------ - @ 1 year 2 mons 3 days 4 hours 5 mins 6.699999 secs -(1 row) - -select interval '0:0:0.7', interval '@ 0.70 secs', interval '0.7 seconds'; - interval | interval | interval -------------+------------+------------ - @ 0.7 secs | @ 0.7 secs | @ 0.7 secs -(1 row) - --- check that '30 days' equals '1 month' according to the hash function -select '30 days'::interval = '1 month'::interval as t; - t ---- - t -(1 row) - -select interval_hash('30 days'::interval) = interval_hash('1 month'::interval) as t; - t ---- - t -(1 row) - --- numeric constructor -select make_interval(years := 2); - make_interval ---------------- - @ 2 years -(1 row) - -select make_interval(years := 1, months := 6); - make_interval ------------------ - @ 1 year 6 mons -(1 row) - -select make_interval(years := 1, months := -1, weeks := 5, days := -7, hours := 25, mins := -180); - make_interval ----------------------------- - @ 11 mons 28 days 22 hours -(1 row) - -select make_interval() = make_interval(years := 0, months := 0, weeks := 0, days := 0, mins := 0, secs := 0.0); - ?column? ----------- - t -(1 row) - -select make_interval(hours := -2, mins := -10, secs := -25.3); - make_interval ---------------------------------- - @ 2 hours 10 mins 25.3 secs ago -(1 row) - -select make_interval(years := 'inf'::float::int); -ERROR: integer out of range -select make_interval(months := 'NaN'::float::int); -ERROR: integer out of range -select make_interval(secs := 'inf'); -ERROR: interval out of range -select make_interval(secs := 'NaN'); -ERROR: interval out of range -select make_interval(secs := 7e12); - make_interval ------------------------------------- - @ 1944444444 hours 26 mins 40 secs -(1 row) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/geometry.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/geometry.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/geometry.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/geometry.out 2022-02-13 01:12:02.955481826 +0100 @@ -3960,933 +3960,8 @@ FROM CIRCLE_TBL c1, POINT_TBL p1 WHERE (p1.f1 <-> c1.f1) > 0 ORDER BY distance, area(c1.f1), p1.f1[0]; - twentyfour | circle | point | distance -------------+----------------+-------------------+--------------- - | <(1,2),3> | (-3,4) | 1.472135955 - | <(5,1),3> | (0,0) | 2.09901951359 - | <(5,1),3> | (1e-300,-1e-300) | 2.09901951359 - | <(5,1),3> | (-3,4) | 5.54400374532 - | <(3,5),0> | (0,0) | 5.83095189485 - | <(3,5),0> | (1e-300,-1e-300) | 5.83095189485 - | <(3,5),0> | (-3,4) | 6.0827625303 - | <(1,3),5> | (-10,0) | 6.40175425099 - | <(1,3),5> | (10,10) | 6.40175425099 - | <(5,1),3> | (10,10) | 7.29563014099 - | <(1,2),3> | (-10,0) | 8.1803398875 - | <(3,5),0> | (10,10) | 8.60232526704 - | <(1,2),3> | (10,10) | 9.04159457879 - | <(1,3),5> | (-5,-12) | 11.1554944214 - | <(5,1),3> | (-10,0) | 12.0332963784 - | <(1,2),3> | (-5,-12) | 12.2315462117 - | <(5,1),3> | (-5,-12) | 13.4012194669 - | <(3,5),0> | (-10,0) | 13.9283882772 - | <(3,5),0> | (-5,-12) | 18.7882942281 - | <(1,3),5> | (5.1,34.5) | 26.7657047773 - | <(3,5),0> | (5.1,34.5) | 29.5746513082 - | <(1,2),3> | (5.1,34.5) | 29.7575945393 - | <(5,1),3> | (5.1,34.5) | 30.5001492534 - | <(100,200),10> | (5.1,34.5) | 180.778038568 - | <(100,200),10> | (10,10) | 200.237960416 - | <(100,200),10> | (-3,4) | 211.415898255 - | <(100,200),10> | (0,0) | 213.60679775 - | <(100,200),10> | (1e-300,-1e-300) | 213.60679775 - | <(100,200),10> | (-10,0) | 218.25424421 - | <(100,200),10> | (-5,-12) | 226.577682802 - | <(3,5),0> | (1e+300,Infinity) | Infinity - | <(1,2),3> | (1e+300,Infinity) | Infinity - | <(5,1),3> | (1e+300,Infinity) | Infinity - | <(1,3),5> | (1e+300,Infinity) | Infinity - | <(100,200),10> | (1e+300,Infinity) | Infinity - | <(1,2),100> | (1e+300,Infinity) | Infinity - | <(100,1),115> | (1e+300,Infinity) | Infinity - | <(3,5),0> | (NaN,NaN) | NaN - | <(1,2),3> | (NaN,NaN) | NaN - | <(5,1),3> | (NaN,NaN) | NaN - | <(1,3),5> | (NaN,NaN) | NaN - | <(100,200),10> | (NaN,NaN) | NaN - | <(1,2),100> | (NaN,NaN) | NaN - | <(100,1),115> | (NaN,NaN) | NaN - | <(3,5),NaN> | (-10,0) | NaN - | <(3,5),NaN> | (-5,-12) | NaN - | <(3,5),NaN> | (-3,4) | NaN - | <(3,5),NaN> | (0,0) | NaN - | <(3,5),NaN> | (1e-300,-1e-300) | NaN - | <(3,5),NaN> | (5.1,34.5) | NaN - | <(3,5),NaN> | (10,10) | NaN - | <(3,5),NaN> | (1e+300,Infinity) | NaN - | <(3,5),NaN> | (NaN,NaN) | NaN -(53 rows) - --- To polygon -SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; - f1 | f1 -----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - <(5,1),3> | ((2,1),(2.40192378865,2.5),(3.5,3.59807621135),(5,4),(6.5,3.59807621135),(7.59807621135,2.5),(8,1),(7.59807621135,-0.5),(6.5,-1.59807621135),(5,-2),(3.5,-1.59807621135),(2.40192378865,-0.5)) - <(1,2),100> | ((-99,2),(-85.6025403784,52),(-49,88.6025403784),(1,102),(51,88.6025403784),(87.6025403784,52),(101,2),(87.6025403784,-48),(51,-84.6025403784),(1,-98),(-49,-84.6025403784),(-85.6025403784,-48)) - <(1,3),5> | ((-4,3),(-3.33012701892,5.5),(-1.5,7.33012701892),(1,8),(3.5,7.33012701892),(5.33012701892,5.5),(6,3),(5.33012701892,0.5),(3.5,-1.33012701892),(1,-2),(-1.5,-1.33012701892),(-3.33012701892,0.5)) - <(1,2),3> | ((-2,2),(-1.59807621135,3.5),(-0.5,4.59807621135),(1,5),(2.5,4.59807621135),(3.59807621135,3.5),(4,2),(3.59807621135,0.5),(2.5,-0.598076211353),(1,-1),(-0.5,-0.598076211353),(-1.59807621135,0.5)) - <(100,200),10> | ((90,200),(91.3397459622,205),(95,208.660254038),(100,210),(105,208.660254038),(108.660254038,205),(110,200),(108.660254038,195),(105,191.339745962),(100,190),(95,191.339745962),(91.3397459622,195)) - <(100,1),115> | ((-15,1),(0.40707856479,58.5),(42.5,100.592921435),(100,116),(157.5,100.592921435),(199.592921435,58.5),(215,1),(199.592921435,-56.5),(157.5,-98.5929214352),(100,-114),(42.5,-98.5929214352),(0.40707856479,-56.5)) -(6 rows) - --- To polygon with less points -SELECT f1, polygon(8, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; - f1 | polygon -----------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------ - <(5,1),3> | ((2,1),(2.87867965644,3.12132034356),(5,4),(7.12132034356,3.12132034356),(8,1),(7.12132034356,-1.12132034356),(5,-2),(2.87867965644,-1.12132034356)) - <(1,2),100> | ((-99,2),(-69.7106781187,72.7106781187),(1,102),(71.7106781187,72.7106781187),(101,2),(71.7106781187,-68.7106781187),(1,-98),(-69.7106781187,-68.7106781187)) - <(1,3),5> | ((-4,3),(-2.53553390593,6.53553390593),(1,8),(4.53553390593,6.53553390593),(6,3),(4.53553390593,-0.535533905933),(1,-2),(-2.53553390593,-0.535533905933)) - <(1,2),3> | ((-2,2),(-1.12132034356,4.12132034356),(1,5),(3.12132034356,4.12132034356),(4,2),(3.12132034356,-0.12132034356),(1,-1),(-1.12132034356,-0.12132034356)) - <(100,200),10> | ((90,200),(92.9289321881,207.071067812),(100,210),(107.071067812,207.071067812),(110,200),(107.071067812,192.928932188),(100,190),(92.9289321881,192.928932188)) - <(100,1),115> | ((-15,1),(18.6827201635,82.3172798365),(100,116),(181.317279836,82.3172798365),(215,1),(181.317279836,-80.3172798365),(100,-114),(18.6827201635,-80.3172798365)) -(6 rows) - --- Too less points error -SELECT f1, polygon(1, f1) FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; -ERROR: must request at least 2 points --- Zero radius error -SELECT f1, polygon(10, f1) FROM CIRCLE_TBL WHERE f1 < '<(0,0),1>'; -ERROR: cannot convert circle with radius zero to polygon --- Same as circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 ~= c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(1,2),100> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(3,5),0> - <(3,5),NaN> | <(3,5),0> - <(3,5),NaN> | <(3,5),NaN> -(9 rows) - --- Overlap with circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 && c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(1,2),3> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(5,1),3> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(1,3),5> - <(1,2),100> | <(1,2),3> - <(1,2),100> | <(100,1),115> - <(1,2),100> | <(3,5),0> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(1,2),3> - <(1,3),5> | <(100,1),115> - <(1,3),5> | <(3,5),0> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(5,1),3> - <(100,1),115> | <(1,2),100> - <(100,1),115> | <(1,3),5> - <(100,1),115> | <(1,2),3> - <(100,1),115> | <(100,1),115> - <(100,1),115> | <(3,5),0> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(33 rows) - --- Overlap or left of circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &< c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(100,200),10> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(100,200),10> - <(100,200),10> | <(100,1),115> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(28 rows) - --- Left of circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 << c2.f1; - f1 | f1 ------------+---------------- - <(5,1),3> | <(100,200),10> - <(1,3),5> | <(100,200),10> - <(1,2),3> | <(100,200),10> - <(3,5),0> | <(100,200),10> -(4 rows) - --- Right of circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >> c2.f1; - f1 | f1 -----------------+----------- - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(3,5),0> -(4 rows) - --- Overlap or right of circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &> c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(1,2),3> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(1,2),100> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,200),10> | <(100,1),115> - <(100,200),10> | <(3,5),0> - <(100,1),115> | <(1,2),100> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(28 rows) - --- Contained by circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <@ c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(1,2),100> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(17 rows) - --- Contain by circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 @> c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(1,2),100> | <(5,1),3> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(1,3),5> - <(1,2),100> | <(1,2),3> - <(1,2),100> | <(3,5),0> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(1,2),3> - <(1,3),5> | <(3,5),0> - <(1,2),3> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(5,1),3> - <(100,1),115> | <(1,3),5> - <(100,1),115> | <(1,2),3> - <(100,1),115> | <(100,1),115> - <(100,1),115> | <(3,5),0> - <(3,5),0> | <(3,5),0> -(17 rows) - --- Below circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <<| c2.f1; - f1 | f1 ----------------+---------------- - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(3,5),0> - <(1,2),100> | <(100,200),10> - <(1,3),5> | <(100,200),10> - <(1,2),3> | <(100,200),10> - <(100,1),115> | <(100,200),10> - <(3,5),0> | <(100,200),10> -(7 rows) - --- Above circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |>> c2.f1; - f1 | f1 -----------------+--------------- - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(100,1),115> - <(100,200),10> | <(3,5),0> - <(3,5),0> | <(5,1),3> -(7 rows) - --- Overlap or below circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 &<| c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(1,2),3> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(5,1),3> | <(3,5),0> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(100,200),10> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(1,2),3> | <(3,5),0> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(100,200),10> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(29 rows) - --- Overlap or above circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 |&> c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,200),10> | <(100,1),115> - <(100,200),10> | <(3,5),0> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(29 rows) - --- Area equal with circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 = c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),3> - <(1,2),100> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(9 rows) - --- Area not equal with circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 != c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(5,1),3> | <(3,5),0> - <(1,2),100> | <(5,1),3> - <(1,2),100> | <(1,3),5> - <(1,2),100> | <(1,2),3> - <(1,2),100> | <(100,200),10> - <(1,2),100> | <(100,1),115> - <(1,2),100> | <(3,5),0> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,2),3> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,3),5> | <(3,5),0> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(1,2),3> | <(3,5),0> - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(100,1),115> - <(100,200),10> | <(3,5),0> - <(100,1),115> | <(5,1),3> - <(100,1),115> | <(1,2),100> - <(100,1),115> | <(1,3),5> - <(100,1),115> | <(1,2),3> - <(100,1),115> | <(100,200),10> - <(100,1),115> | <(3,5),0> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> -(40 rows) - --- Area less than circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> -(20 rows) - --- Area greater than circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 > c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(3,5),0> - <(1,2),100> | <(5,1),3> - <(1,2),100> | <(1,3),5> - <(1,2),100> | <(1,2),3> - <(1,2),100> | <(100,200),10> - <(1,2),100> | <(3,5),0> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,2),3> - <(1,3),5> | <(3,5),0> - <(1,2),3> | <(3,5),0> - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(3,5),0> - <(100,1),115> | <(5,1),3> - <(100,1),115> | <(1,2),100> - <(100,1),115> | <(1,3),5> - <(100,1),115> | <(1,2),3> - <(100,1),115> | <(100,200),10> - <(100,1),115> | <(3,5),0> -(20 rows) - --- Area less than or equal circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 <= c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(1,2),3> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(100,200),10> - <(100,200),10> | <(100,1),115> - <(100,1),115> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> - <(3,5),0> | <(3,5),0> -(29 rows) - --- Area greater than or equal circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 >= c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(5,1),3> - <(5,1),3> | <(1,2),3> - <(5,1),3> | <(3,5),0> - <(1,2),100> | <(5,1),3> - <(1,2),100> | <(1,2),100> - <(1,2),100> | <(1,3),5> - <(1,2),100> | <(1,2),3> - <(1,2),100> | <(100,200),10> - <(1,2),100> | <(3,5),0> - <(1,3),5> | <(5,1),3> - <(1,3),5> | <(1,3),5> - <(1,3),5> | <(1,2),3> - <(1,3),5> | <(3,5),0> - <(1,2),3> | <(5,1),3> - <(1,2),3> | <(1,2),3> - <(1,2),3> | <(3,5),0> - <(100,200),10> | <(5,1),3> - <(100,200),10> | <(1,3),5> - <(100,200),10> | <(1,2),3> - <(100,200),10> | <(100,200),10> - <(100,200),10> | <(3,5),0> - <(100,1),115> | <(5,1),3> - <(100,1),115> | <(1,2),100> - <(100,1),115> | <(1,3),5> - <(100,1),115> | <(1,2),3> - <(100,1),115> | <(100,200),10> - <(100,1),115> | <(100,1),115> - <(100,1),115> | <(3,5),0> - <(3,5),0> | <(3,5),0> -(29 rows) - --- Area less than circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> -(20 rows) - --- Area greater than circle -SELECT c1.f1, c2.f1 FROM CIRCLE_TBL c1, CIRCLE_TBL c2 WHERE c1.f1 < c2.f1; - f1 | f1 -----------------+---------------- - <(5,1),3> | <(1,2),100> - <(5,1),3> | <(1,3),5> - <(5,1),3> | <(100,200),10> - <(5,1),3> | <(100,1),115> - <(1,2),100> | <(100,1),115> - <(1,3),5> | <(1,2),100> - <(1,3),5> | <(100,200),10> - <(1,3),5> | <(100,1),115> - <(1,2),3> | <(1,2),100> - <(1,2),3> | <(1,3),5> - <(1,2),3> | <(100,200),10> - <(1,2),3> | <(100,1),115> - <(100,200),10> | <(1,2),100> - <(100,200),10> | <(100,1),115> - <(3,5),0> | <(5,1),3> - <(3,5),0> | <(1,2),100> - <(3,5),0> | <(1,3),5> - <(3,5),0> | <(1,2),3> - <(3,5),0> | <(100,200),10> - <(3,5),0> | <(100,1),115> -(20 rows) - --- Add point -SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; - f1 | f1 | ?column? -----------------+-------------------+------------------------- - <(5,1),3> | (0,0) | <(5,1),3> - <(1,2),100> | (0,0) | <(1,2),100> - <(1,3),5> | (0,0) | <(1,3),5> - <(1,2),3> | (0,0) | <(1,2),3> - <(100,200),10> | (0,0) | <(100,200),10> - <(100,1),115> | (0,0) | <(100,1),115> - <(3,5),0> | (0,0) | <(3,5),0> - <(3,5),NaN> | (0,0) | <(3,5),NaN> - <(5,1),3> | (-10,0) | <(-5,1),3> - <(1,2),100> | (-10,0) | <(-9,2),100> - <(1,3),5> | (-10,0) | <(-9,3),5> - <(1,2),3> | (-10,0) | <(-9,2),3> - <(100,200),10> | (-10,0) | <(90,200),10> - <(100,1),115> | (-10,0) | <(90,1),115> - <(3,5),0> | (-10,0) | <(-7,5),0> - <(3,5),NaN> | (-10,0) | <(-7,5),NaN> - <(5,1),3> | (-3,4) | <(2,5),3> - <(1,2),100> | (-3,4) | <(-2,6),100> - <(1,3),5> | (-3,4) | <(-2,7),5> - <(1,2),3> | (-3,4) | <(-2,6),3> - <(100,200),10> | (-3,4) | <(97,204),10> - <(100,1),115> | (-3,4) | <(97,5),115> - <(3,5),0> | (-3,4) | <(0,9),0> - <(3,5),NaN> | (-3,4) | <(0,9),NaN> - <(5,1),3> | (5.1,34.5) | <(10.1,35.5),3> - <(1,2),100> | (5.1,34.5) | <(6.1,36.5),100> - <(1,3),5> | (5.1,34.5) | <(6.1,37.5),5> - <(1,2),3> | (5.1,34.5) | <(6.1,36.5),3> - <(100,200),10> | (5.1,34.5) | <(105.1,234.5),10> - <(100,1),115> | (5.1,34.5) | <(105.1,35.5),115> - <(3,5),0> | (5.1,34.5) | <(8.1,39.5),0> - <(3,5),NaN> | (5.1,34.5) | <(8.1,39.5),NaN> - <(5,1),3> | (-5,-12) | <(0,-11),3> - <(1,2),100> | (-5,-12) | <(-4,-10),100> - <(1,3),5> | (-5,-12) | <(-4,-9),5> - <(1,2),3> | (-5,-12) | <(-4,-10),3> - <(100,200),10> | (-5,-12) | <(95,188),10> - <(100,1),115> | (-5,-12) | <(95,-11),115> - <(3,5),0> | (-5,-12) | <(-2,-7),0> - <(3,5),NaN> | (-5,-12) | <(-2,-7),NaN> - <(5,1),3> | (1e-300,-1e-300) | <(5,1),3> - <(1,2),100> | (1e-300,-1e-300) | <(1,2),100> - <(1,3),5> | (1e-300,-1e-300) | <(1,3),5> - <(1,2),3> | (1e-300,-1e-300) | <(1,2),3> - <(100,200),10> | (1e-300,-1e-300) | <(100,200),10> - <(100,1),115> | (1e-300,-1e-300) | <(100,1),115> - <(3,5),0> | (1e-300,-1e-300) | <(3,5),0> - <(3,5),NaN> | (1e-300,-1e-300) | <(3,5),NaN> - <(5,1),3> | (1e+300,Infinity) | <(1e+300,Infinity),3> - <(1,2),100> | (1e+300,Infinity) | <(1e+300,Infinity),100> - <(1,3),5> | (1e+300,Infinity) | <(1e+300,Infinity),5> - <(1,2),3> | (1e+300,Infinity) | <(1e+300,Infinity),3> - <(100,200),10> | (1e+300,Infinity) | <(1e+300,Infinity),10> - <(100,1),115> | (1e+300,Infinity) | <(1e+300,Infinity),115> - <(3,5),0> | (1e+300,Infinity) | <(1e+300,Infinity),0> - <(3,5),NaN> | (1e+300,Infinity) | <(1e+300,Infinity),NaN> - <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> - <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> - <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> - <(1,2),3> | (NaN,NaN) | <(NaN,NaN),3> - <(100,200),10> | (NaN,NaN) | <(NaN,NaN),10> - <(100,1),115> | (NaN,NaN) | <(NaN,NaN),115> - <(3,5),0> | (NaN,NaN) | <(NaN,NaN),0> - <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> - <(5,1),3> | (10,10) | <(15,11),3> - <(1,2),100> | (10,10) | <(11,12),100> - <(1,3),5> | (10,10) | <(11,13),5> - <(1,2),3> | (10,10) | <(11,12),3> - <(100,200),10> | (10,10) | <(110,210),10> - <(100,1),115> | (10,10) | <(110,11),115> - <(3,5),0> | (10,10) | <(13,15),0> - <(3,5),NaN> | (10,10) | <(13,15),NaN> -(72 rows) - --- Subtract point -SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; - f1 | f1 | ?column? -----------------+-------------------+--------------------------- - <(5,1),3> | (0,0) | <(5,1),3> - <(1,2),100> | (0,0) | <(1,2),100> - <(1,3),5> | (0,0) | <(1,3),5> - <(1,2),3> | (0,0) | <(1,2),3> - <(100,200),10> | (0,0) | <(100,200),10> - <(100,1),115> | (0,0) | <(100,1),115> - <(3,5),0> | (0,0) | <(3,5),0> - <(3,5),NaN> | (0,0) | <(3,5),NaN> - <(5,1),3> | (-10,0) | <(15,1),3> - <(1,2),100> | (-10,0) | <(11,2),100> - <(1,3),5> | (-10,0) | <(11,3),5> - <(1,2),3> | (-10,0) | <(11,2),3> - <(100,200),10> | (-10,0) | <(110,200),10> - <(100,1),115> | (-10,0) | <(110,1),115> - <(3,5),0> | (-10,0) | <(13,5),0> - <(3,5),NaN> | (-10,0) | <(13,5),NaN> - <(5,1),3> | (-3,4) | <(8,-3),3> - <(1,2),100> | (-3,4) | <(4,-2),100> - <(1,3),5> | (-3,4) | <(4,-1),5> - <(1,2),3> | (-3,4) | <(4,-2),3> - <(100,200),10> | (-3,4) | <(103,196),10> - <(100,1),115> | (-3,4) | <(103,-3),115> - <(3,5),0> | (-3,4) | <(6,1),0> - <(3,5),NaN> | (-3,4) | <(6,1),NaN> - <(5,1),3> | (5.1,34.5) | <(-0.1,-33.5),3> - <(1,2),100> | (5.1,34.5) | <(-4.1,-32.5),100> - <(1,3),5> | (5.1,34.5) | <(-4.1,-31.5),5> - <(1,2),3> | (5.1,34.5) | <(-4.1,-32.5),3> - <(100,200),10> | (5.1,34.5) | <(94.9,165.5),10> - <(100,1),115> | (5.1,34.5) | <(94.9,-33.5),115> - <(3,5),0> | (5.1,34.5) | <(-2.1,-29.5),0> - <(3,5),NaN> | (5.1,34.5) | <(-2.1,-29.5),NaN> - <(5,1),3> | (-5,-12) | <(10,13),3> - <(1,2),100> | (-5,-12) | <(6,14),100> - <(1,3),5> | (-5,-12) | <(6,15),5> - <(1,2),3> | (-5,-12) | <(6,14),3> - <(100,200),10> | (-5,-12) | <(105,212),10> - <(100,1),115> | (-5,-12) | <(105,13),115> - <(3,5),0> | (-5,-12) | <(8,17),0> - <(3,5),NaN> | (-5,-12) | <(8,17),NaN> - <(5,1),3> | (1e-300,-1e-300) | <(5,1),3> - <(1,2),100> | (1e-300,-1e-300) | <(1,2),100> - <(1,3),5> | (1e-300,-1e-300) | <(1,3),5> - <(1,2),3> | (1e-300,-1e-300) | <(1,2),3> - <(100,200),10> | (1e-300,-1e-300) | <(100,200),10> - <(100,1),115> | (1e-300,-1e-300) | <(100,1),115> - <(3,5),0> | (1e-300,-1e-300) | <(3,5),0> - <(3,5),NaN> | (1e-300,-1e-300) | <(3,5),NaN> - <(5,1),3> | (1e+300,Infinity) | <(-1e+300,-Infinity),3> - <(1,2),100> | (1e+300,Infinity) | <(-1e+300,-Infinity),100> - <(1,3),5> | (1e+300,Infinity) | <(-1e+300,-Infinity),5> - <(1,2),3> | (1e+300,Infinity) | <(-1e+300,-Infinity),3> - <(100,200),10> | (1e+300,Infinity) | <(-1e+300,-Infinity),10> - <(100,1),115> | (1e+300,Infinity) | <(-1e+300,-Infinity),115> - <(3,5),0> | (1e+300,Infinity) | <(-1e+300,-Infinity),0> - <(3,5),NaN> | (1e+300,Infinity) | <(-1e+300,-Infinity),NaN> - <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> - <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> - <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> - <(1,2),3> | (NaN,NaN) | <(NaN,NaN),3> - <(100,200),10> | (NaN,NaN) | <(NaN,NaN),10> - <(100,1),115> | (NaN,NaN) | <(NaN,NaN),115> - <(3,5),0> | (NaN,NaN) | <(NaN,NaN),0> - <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> - <(5,1),3> | (10,10) | <(-5,-9),3> - <(1,2),100> | (10,10) | <(-9,-8),100> - <(1,3),5> | (10,10) | <(-9,-7),5> - <(1,2),3> | (10,10) | <(-9,-8),3> - <(100,200),10> | (10,10) | <(90,190),10> - <(100,1),115> | (10,10) | <(90,-9),115> - <(3,5),0> | (10,10) | <(-7,-5),0> - <(3,5),NaN> | (10,10) | <(-7,-5),NaN> -(72 rows) - --- Multiply with point -SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; - f1 | f1 | ?column? -----------------+-------------------+-------------------------------------------- - <(5,1),3> | (0,0) | <(0,0),0> - <(1,2),100> | (0,0) | <(0,0),0> - <(1,3),5> | (0,0) | <(0,0),0> - <(1,2),3> | (0,0) | <(0,0),0> - <(100,200),10> | (0,0) | <(0,0),0> - <(100,1),115> | (0,0) | <(0,0),0> - <(3,5),0> | (0,0) | <(0,0),0> - <(3,5),NaN> | (0,0) | <(0,0),NaN> - <(5,1),3> | (-10,0) | <(-50,-10),30> - <(1,2),100> | (-10,0) | <(-10,-20),1000> - <(1,3),5> | (-10,0) | <(-10,-30),50> - <(1,2),3> | (-10,0) | <(-10,-20),30> - <(100,200),10> | (-10,0) | <(-1000,-2000),100> - <(100,1),115> | (-10,0) | <(-1000,-10),1150> - <(3,5),0> | (-10,0) | <(-30,-50),0> - <(3,5),NaN> | (-10,0) | <(-30,-50),NaN> - <(5,1),3> | (-3,4) | <(-19,17),15> - <(1,2),100> | (-3,4) | <(-11,-2),500> - <(1,3),5> | (-3,4) | <(-15,-5),25> - <(1,2),3> | (-3,4) | <(-11,-2),15> - <(100,200),10> | (-3,4) | <(-1100,-200),50> - <(100,1),115> | (-3,4) | <(-304,397),575> - <(3,5),0> | (-3,4) | <(-29,-3),0> - <(3,5),NaN> | (-3,4) | <(-29,-3),NaN> - <(5,1),3> | (5.1,34.5) | <(-9,177.6),104.624758064> - <(1,2),100> | (5.1,34.5) | <(-63.9,44.7),3487.49193547> - <(1,3),5> | (5.1,34.5) | <(-98.4,49.8),174.374596774> - <(1,2),3> | (5.1,34.5) | <(-63.9,44.7),104.624758064> - <(100,200),10> | (5.1,34.5) | <(-6390,4470),348.749193547> - <(100,1),115> | (5.1,34.5) | <(475.5,3455.1),4010.6157258> - <(3,5),0> | (5.1,34.5) | <(-157.2,129),0> - <(3,5),NaN> | (5.1,34.5) | <(-157.2,129),NaN> - <(5,1),3> | (-5,-12) | <(-13,-65),39> - <(1,2),100> | (-5,-12) | <(19,-22),1300> - <(1,3),5> | (-5,-12) | <(31,-27),65> - <(1,2),3> | (-5,-12) | <(19,-22),39> - <(100,200),10> | (-5,-12) | <(1900,-2200),130> - <(100,1),115> | (-5,-12) | <(-488,-1205),1495> - <(3,5),0> | (-5,-12) | <(45,-61),0> - <(3,5),NaN> | (-5,-12) | <(45,-61),NaN> - <(5,1),3> | (1e-300,-1e-300) | <(6e-300,-4e-300),4.24264068712e-300> - <(1,2),100> | (1e-300,-1e-300) | <(3e-300,1e-300),1.41421356237e-298> - <(1,3),5> | (1e-300,-1e-300) | <(4e-300,2e-300),7.07106781187e-300> - <(1,2),3> | (1e-300,-1e-300) | <(3e-300,1e-300),4.24264068712e-300> - <(100,200),10> | (1e-300,-1e-300) | <(3e-298,1e-298),1.41421356237e-299> - <(100,1),115> | (1e-300,-1e-300) | <(1.01e-298,-9.9e-299),1.62634559673e-298> - <(3,5),0> | (1e-300,-1e-300) | <(8e-300,2e-300),0> - <(3,5),NaN> | (1e-300,-1e-300) | <(8e-300,2e-300),NaN> - <(5,1),3> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(1,2),100> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(1,3),5> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(1,2),3> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(100,200),10> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(100,1),115> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> - <(3,5),0> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> - <(3,5),NaN> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> - <(5,1),3> | (NaN,NaN) | <(NaN,NaN),NaN> - <(1,2),100> | (NaN,NaN) | <(NaN,NaN),NaN> - <(1,3),5> | (NaN,NaN) | <(NaN,NaN),NaN> - <(1,2),3> | (NaN,NaN) | <(NaN,NaN),NaN> - <(100,200),10> | (NaN,NaN) | <(NaN,NaN),NaN> - <(100,1),115> | (NaN,NaN) | <(NaN,NaN),NaN> - <(3,5),0> | (NaN,NaN) | <(NaN,NaN),NaN> - <(3,5),NaN> | (NaN,NaN) | <(NaN,NaN),NaN> - <(5,1),3> | (10,10) | <(40,60),42.4264068712> - <(1,2),100> | (10,10) | <(-10,30),1414.21356237> - <(1,3),5> | (10,10) | <(-20,40),70.7106781187> - <(1,2),3> | (10,10) | <(-10,30),42.4264068712> - <(100,200),10> | (10,10) | <(-1000,3000),141.421356237> - <(100,1),115> | (10,10) | <(990,1010),1626.34559673> - <(3,5),0> | (10,10) | <(-20,80),0> - <(3,5),NaN> | (10,10) | <(-20,80),NaN> -(72 rows) - --- Divide by point -SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; - f1 | f1 | ?column? -----------------+------------+------------------------------------------------------ - <(5,1),3> | (5.1,34.5) | <(0.0493315573973,-0.137635045138),0.0860217042937> - <(5,1),3> | (10,10) | <(0.3,-0.2),0.212132034356> - <(1,2),100> | (5.1,34.5) | <(0.0609244733856,-0.0199792807459),2.86739014312> - <(1,2),100> | (10,10) | <(0.15,0.05),7.07106781187> - <(1,3),5> | (5.1,34.5) | <(0.0892901188891,-0.0157860983671),0.143369507156> - <(1,3),5> | (10,10) | <(0.2,0.1),0.353553390593> - <(1,2),3> | (5.1,34.5) | <(0.0609244733856,-0.0199792807459),0.0860217042937> - <(1,2),3> | (10,10) | <(0.15,0.05),0.212132034356> - <(100,200),10> | (5.1,34.5) | <(6.09244733856,-1.99792807459),0.286739014312> - <(100,200),10> | (10,10) | <(15,5),0.707106781187> - <(100,1),115> | (5.1,34.5) | <(0.44768388338,-2.83237136796),3.29749866459> - <(100,1),115> | (10,10) | <(5.05,-4.95),8.13172798365> - <(3,5),0> | (5.1,34.5) | <(0.154407774653,-0.0641310246164),0> - <(3,5),0> | (10,10) | <(0.4,0.1),0> - <(3,5),NaN> | (5.1,34.5) | <(0.154407774653,-0.0641310246164),NaN> - <(3,5),NaN> | (10,10) | <(0.4,0.1),NaN> -(16 rows) - --- Overflow error -SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] > 1000; -ERROR: value out of range: overflow --- Division by 0 error -SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1 ~= '(0,0)'::point; -ERROR: division by zero --- Distance to polygon -SELECT c.f1, p.f1, c.f1 <-> p.f1 FROM CIRCLE_TBL c, POLYGON_TBL p; - f1 | f1 | ?column? -----------------+----------------------------+---------------- - <(5,1),3> | ((2,0),(2,4),(0,0)) | 0 - <(5,1),3> | ((3,1),(3,3),(1,0)) | 0 - <(5,1),3> | ((1,2),(3,4),(5,6),(7,8)) | 0.535533905933 - <(5,1),3> | ((7,8),(5,6),(3,4),(1,2)) | 0.535533905933 - <(5,1),3> | ((1,2),(7,8),(5,6),(3,-4)) | 0 - <(5,1),3> | ((0,0)) | 2.09901951359 - <(5,1),3> | ((0,1),(0,1)) | 2 - <(1,2),100> | ((2,0),(2,4),(0,0)) | 0 - <(1,2),100> | ((3,1),(3,3),(1,0)) | 0 - <(1,2),100> | ((1,2),(3,4),(5,6),(7,8)) | 0 - <(1,2),100> | ((7,8),(5,6),(3,4),(1,2)) | 0 - <(1,2),100> | ((1,2),(7,8),(5,6),(3,-4)) | 0 - <(1,2),100> | ((0,0)) | 0 - <(1,2),100> | ((0,1),(0,1)) | 0 - <(1,3),5> | ((2,0),(2,4),(0,0)) | 0 - <(1,3),5> | ((3,1),(3,3),(1,0)) | 0 - <(1,3),5> | ((1,2),(3,4),(5,6),(7,8)) | 0 - <(1,3),5> | ((7,8),(5,6),(3,4),(1,2)) | 0 - <(1,3),5> | ((1,2),(7,8),(5,6),(3,-4)) | 0 - <(1,3),5> | ((0,0)) | 0 - <(1,3),5> | ((0,1),(0,1)) | 0 - <(1,2),3> | ((2,0),(2,4),(0,0)) | 0 - <(1,2),3> | ((3,1),(3,3),(1,0)) | 0 - <(1,2),3> | ((1,2),(3,4),(5,6),(7,8)) | 0 - <(1,2),3> | ((7,8),(5,6),(3,4),(1,2)) | 0 - <(1,2),3> | ((1,2),(7,8),(5,6),(3,-4)) | 0 - <(1,2),3> | ((0,0)) | 0 - <(1,2),3> | ((0,1),(0,1)) | 0 - <(100,200),10> | ((2,0),(2,4),(0,0)) | 209.134661795 - <(100,200),10> | ((3,1),(3,3),(1,0)) | 209.585974051 - <(100,200),10> | ((1,2),(3,4),(5,6),(7,8)) | 203.337760371 - <(100,200),10> | ((7,8),(5,6),(3,4),(1,2)) | 203.337760371 - <(100,200),10> | ((1,2),(7,8),(5,6),(3,-4)) | 203.337760371 - <(100,200),10> | ((0,0)) | 213.60679775 - <(100,200),10> | ((0,1),(0,1)) | 212.712819568 - <(100,1),115> | ((2,0),(2,4),(0,0)) | 0 - <(100,1),115> | ((3,1),(3,3),(1,0)) | 0 - <(100,1),115> | ((1,2),(3,4),(5,6),(7,8)) | 0 - <(100,1),115> | ((7,8),(5,6),(3,4),(1,2)) | 0 - <(100,1),115> | ((1,2),(7,8),(5,6),(3,-4)) | 0 - <(100,1),115> | ((0,0)) | 0 - <(100,1),115> | ((0,1),(0,1)) | 0 - <(3,5),0> | ((2,0),(2,4),(0,0)) | 1.41421356237 - <(3,5),0> | ((3,1),(3,3),(1,0)) | 2 - <(3,5),0> | ((1,2),(3,4),(5,6),(7,8)) | 0.707106781187 - <(3,5),0> | ((7,8),(5,6),(3,4),(1,2)) | 0.707106781187 - <(3,5),0> | ((1,2),(7,8),(5,6),(3,-4)) | 0.707106781187 - <(3,5),0> | ((0,0)) | 5.83095189485 - <(3,5),0> | ((0,1),(0,1)) | 5 - <(3,5),NaN> | ((2,0),(2,4),(0,0)) | NaN - <(3,5),NaN> | ((3,1),(3,3),(1,0)) | NaN - <(3,5),NaN> | ((1,2),(3,4),(5,6),(7,8)) | NaN - <(3,5),NaN> | ((7,8),(5,6),(3,4),(1,2)) | NaN - <(3,5),NaN> | ((1,2),(7,8),(5,6),(3,-4)) | NaN - <(3,5),NaN> | ((0,0)) | NaN - <(3,5),NaN> | ((0,1),(0,1)) | NaN -(56 rows) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/horology.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/horology.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/horology.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/horology.out 2022-02-13 01:12:02.728814777 +0100 @@ -1051,2294 +1051,8 @@ SELECT t.f1 AS t, i.f1 AS i, t.f1 + i.f1 AS "add", t.f1 - i.f1 AS "subtract" FROM TIME_TBL t, INTERVAL_TBL i ORDER BY 1,2; - t | i | add | subtract --------------+-------------------------------+-------------+------------- - 00:00:00 | @ 14 secs ago | 23:59:46 | 00:00:14 - 00:00:00 | @ 1 min | 00:01:00 | 23:59:00 - 00:00:00 | @ 5 hours | 05:00:00 | 19:00:00 - 00:00:00 | @ 1 day 2 hours 3 mins 4 secs | 02:03:04 | 21:56:56 - 00:00:00 | @ 10 days | 00:00:00 | 00:00:00 - 00:00:00 | @ 3 mons | 00:00:00 | 00:00:00 - 00:00:00 | @ 5 mons | 00:00:00 | 00:00:00 - 00:00:00 | @ 5 mons 12 hours | 12:00:00 | 12:00:00 - 00:00:00 | @ 6 years | 00:00:00 | 00:00:00 - 00:00:00 | @ 34 years | 00:00:00 | 00:00:00 - 01:00:00 | @ 14 secs ago | 00:59:46 | 01:00:14 - 01:00:00 | @ 1 min | 01:01:00 | 00:59:00 - 01:00:00 | @ 5 hours | 06:00:00 | 20:00:00 - 01:00:00 | @ 1 day 2 hours 3 mins 4 secs | 03:03:04 | 22:56:56 - 01:00:00 | @ 10 days | 01:00:00 | 01:00:00 - 01:00:00 | @ 3 mons | 01:00:00 | 01:00:00 - 01:00:00 | @ 5 mons | 01:00:00 | 01:00:00 - 01:00:00 | @ 5 mons 12 hours | 13:00:00 | 13:00:00 - 01:00:00 | @ 6 years | 01:00:00 | 01:00:00 - 01:00:00 | @ 34 years | 01:00:00 | 01:00:00 - 02:03:00 | @ 14 secs ago | 02:02:46 | 02:03:14 - 02:03:00 | @ 1 min | 02:04:00 | 02:02:00 - 02:03:00 | @ 5 hours | 07:03:00 | 21:03:00 - 02:03:00 | @ 1 day 2 hours 3 mins 4 secs | 04:06:04 | 23:59:56 - 02:03:00 | @ 10 days | 02:03:00 | 02:03:00 - 02:03:00 | @ 3 mons | 02:03:00 | 02:03:00 - 02:03:00 | @ 5 mons | 02:03:00 | 02:03:00 - 02:03:00 | @ 5 mons 12 hours | 14:03:00 | 14:03:00 - 02:03:00 | @ 6 years | 02:03:00 | 02:03:00 - 02:03:00 | @ 34 years | 02:03:00 | 02:03:00 - 11:59:00 | @ 14 secs ago | 11:58:46 | 11:59:14 - 11:59:00 | @ 1 min | 12:00:00 | 11:58:00 - 11:59:00 | @ 5 hours | 16:59:00 | 06:59:00 - 11:59:00 | @ 1 day 2 hours 3 mins 4 secs | 14:02:04 | 09:55:56 - 11:59:00 | @ 10 days | 11:59:00 | 11:59:00 - 11:59:00 | @ 3 mons | 11:59:00 | 11:59:00 - 11:59:00 | @ 5 mons | 11:59:00 | 11:59:00 - 11:59:00 | @ 5 mons 12 hours | 23:59:00 | 23:59:00 - 11:59:00 | @ 6 years | 11:59:00 | 11:59:00 - 11:59:00 | @ 34 years | 11:59:00 | 11:59:00 - 12:00:00 | @ 14 secs ago | 11:59:46 | 12:00:14 - 12:00:00 | @ 1 min | 12:01:00 | 11:59:00 - 12:00:00 | @ 5 hours | 17:00:00 | 07:00:00 - 12:00:00 | @ 1 day 2 hours 3 mins 4 secs | 14:03:04 | 09:56:56 - 12:00:00 | @ 10 days | 12:00:00 | 12:00:00 - 12:00:00 | @ 3 mons | 12:00:00 | 12:00:00 - 12:00:00 | @ 5 mons | 12:00:00 | 12:00:00 - 12:00:00 | @ 5 mons 12 hours | 00:00:00 | 00:00:00 - 12:00:00 | @ 6 years | 12:00:00 | 12:00:00 - 12:00:00 | @ 34 years | 12:00:00 | 12:00:00 - 12:01:00 | @ 14 secs ago | 12:00:46 | 12:01:14 - 12:01:00 | @ 1 min | 12:02:00 | 12:00:00 - 12:01:00 | @ 5 hours | 17:01:00 | 07:01:00 - 12:01:00 | @ 1 day 2 hours 3 mins 4 secs | 14:04:04 | 09:57:56 - 12:01:00 | @ 10 days | 12:01:00 | 12:01:00 - 12:01:00 | @ 3 mons | 12:01:00 | 12:01:00 - 12:01:00 | @ 5 mons | 12:01:00 | 12:01:00 - 12:01:00 | @ 5 mons 12 hours | 00:01:00 | 00:01:00 - 12:01:00 | @ 6 years | 12:01:00 | 12:01:00 - 12:01:00 | @ 34 years | 12:01:00 | 12:01:00 - 15:36:39 | @ 14 secs ago | 15:36:25 | 15:36:53 - 15:36:39 | @ 14 secs ago | 15:36:25 | 15:36:53 - 15:36:39 | @ 1 min | 15:37:39 | 15:35:39 - 15:36:39 | @ 1 min | 15:37:39 | 15:35:39 - 15:36:39 | @ 5 hours | 20:36:39 | 10:36:39 - 15:36:39 | @ 5 hours | 20:36:39 | 10:36:39 - 15:36:39 | @ 1 day 2 hours 3 mins 4 secs | 17:39:43 | 13:33:35 - 15:36:39 | @ 1 day 2 hours 3 mins 4 secs | 17:39:43 | 13:33:35 - 15:36:39 | @ 10 days | 15:36:39 | 15:36:39 - 15:36:39 | @ 10 days | 15:36:39 | 15:36:39 - 15:36:39 | @ 3 mons | 15:36:39 | 15:36:39 - 15:36:39 | @ 3 mons | 15:36:39 | 15:36:39 - 15:36:39 | @ 5 mons | 15:36:39 | 15:36:39 - 15:36:39 | @ 5 mons | 15:36:39 | 15:36:39 - 15:36:39 | @ 5 mons 12 hours | 03:36:39 | 03:36:39 - 15:36:39 | @ 5 mons 12 hours | 03:36:39 | 03:36:39 - 15:36:39 | @ 6 years | 15:36:39 | 15:36:39 - 15:36:39 | @ 6 years | 15:36:39 | 15:36:39 - 15:36:39 | @ 34 years | 15:36:39 | 15:36:39 - 15:36:39 | @ 34 years | 15:36:39 | 15:36:39 - 23:59:00 | @ 14 secs ago | 23:58:46 | 23:59:14 - 23:59:00 | @ 1 min | 00:00:00 | 23:58:00 - 23:59:00 | @ 5 hours | 04:59:00 | 18:59:00 - 23:59:00 | @ 1 day 2 hours 3 mins 4 secs | 02:02:04 | 21:55:56 - 23:59:00 | @ 10 days | 23:59:00 | 23:59:00 - 23:59:00 | @ 3 mons | 23:59:00 | 23:59:00 - 23:59:00 | @ 5 mons | 23:59:00 | 23:59:00 - 23:59:00 | @ 5 mons 12 hours | 11:59:00 | 11:59:00 - 23:59:00 | @ 6 years | 23:59:00 | 23:59:00 - 23:59:00 | @ 34 years | 23:59:00 | 23:59:00 - 23:59:59.99 | @ 14 secs ago | 23:59:45.99 | 00:00:13.99 - 23:59:59.99 | @ 1 min | 00:00:59.99 | 23:58:59.99 - 23:59:59.99 | @ 5 hours | 04:59:59.99 | 18:59:59.99 - 23:59:59.99 | @ 1 day 2 hours 3 mins 4 secs | 02:03:03.99 | 21:56:55.99 - 23:59:59.99 | @ 10 days | 23:59:59.99 | 23:59:59.99 - 23:59:59.99 | @ 3 mons | 23:59:59.99 | 23:59:59.99 - 23:59:59.99 | @ 5 mons | 23:59:59.99 | 23:59:59.99 - 23:59:59.99 | @ 5 mons 12 hours | 11:59:59.99 | 11:59:59.99 - 23:59:59.99 | @ 6 years | 23:59:59.99 | 23:59:59.99 - 23:59:59.99 | @ 34 years | 23:59:59.99 | 23:59:59.99 -(100 rows) - -SELECT t.f1 AS t, i.f1 AS i, t.f1 + i.f1 AS "add", t.f1 - i.f1 AS "subtract" - FROM TIMETZ_TBL t, INTERVAL_TBL i - ORDER BY 1,2; - t | i | add | subtract -----------------+-------------------------------+----------------+---------------- - 00:01:00-07 | @ 14 secs ago | 00:00:46-07 | 00:01:14-07 - 00:01:00-07 | @ 1 min | 00:02:00-07 | 00:00:00-07 - 00:01:00-07 | @ 5 hours | 05:01:00-07 | 19:01:00-07 - 00:01:00-07 | @ 1 day 2 hours 3 mins 4 secs | 02:04:04-07 | 21:57:56-07 - 00:01:00-07 | @ 10 days | 00:01:00-07 | 00:01:00-07 - 00:01:00-07 | @ 3 mons | 00:01:00-07 | 00:01:00-07 - 00:01:00-07 | @ 5 mons | 00:01:00-07 | 00:01:00-07 - 00:01:00-07 | @ 5 mons 12 hours | 12:01:00-07 | 12:01:00-07 - 00:01:00-07 | @ 6 years | 00:01:00-07 | 00:01:00-07 - 00:01:00-07 | @ 34 years | 00:01:00-07 | 00:01:00-07 - 01:00:00-07 | @ 14 secs ago | 00:59:46-07 | 01:00:14-07 - 01:00:00-07 | @ 1 min | 01:01:00-07 | 00:59:00-07 - 01:00:00-07 | @ 5 hours | 06:00:00-07 | 20:00:00-07 - 01:00:00-07 | @ 1 day 2 hours 3 mins 4 secs | 03:03:04-07 | 22:56:56-07 - 01:00:00-07 | @ 10 days | 01:00:00-07 | 01:00:00-07 - 01:00:00-07 | @ 3 mons | 01:00:00-07 | 01:00:00-07 - 01:00:00-07 | @ 5 mons | 01:00:00-07 | 01:00:00-07 - 01:00:00-07 | @ 5 mons 12 hours | 13:00:00-07 | 13:00:00-07 - 01:00:00-07 | @ 6 years | 01:00:00-07 | 01:00:00-07 - 01:00:00-07 | @ 34 years | 01:00:00-07 | 01:00:00-07 - 02:03:00-07 | @ 14 secs ago | 02:02:46-07 | 02:03:14-07 - 02:03:00-07 | @ 1 min | 02:04:00-07 | 02:02:00-07 - 02:03:00-07 | @ 5 hours | 07:03:00-07 | 21:03:00-07 - 02:03:00-07 | @ 1 day 2 hours 3 mins 4 secs | 04:06:04-07 | 23:59:56-07 - 02:03:00-07 | @ 10 days | 02:03:00-07 | 02:03:00-07 - 02:03:00-07 | @ 3 mons | 02:03:00-07 | 02:03:00-07 - 02:03:00-07 | @ 5 mons | 02:03:00-07 | 02:03:00-07 - 02:03:00-07 | @ 5 mons 12 hours | 14:03:00-07 | 14:03:00-07 - 02:03:00-07 | @ 6 years | 02:03:00-07 | 02:03:00-07 - 02:03:00-07 | @ 34 years | 02:03:00-07 | 02:03:00-07 - 08:08:00-04 | @ 14 secs ago | 08:07:46-04 | 08:08:14-04 - 08:08:00-04 | @ 1 min | 08:09:00-04 | 08:07:00-04 - 08:08:00-04 | @ 5 hours | 13:08:00-04 | 03:08:00-04 - 08:08:00-04 | @ 1 day 2 hours 3 mins 4 secs | 10:11:04-04 | 06:04:56-04 - 08:08:00-04 | @ 10 days | 08:08:00-04 | 08:08:00-04 - 08:08:00-04 | @ 3 mons | 08:08:00-04 | 08:08:00-04 - 08:08:00-04 | @ 5 mons | 08:08:00-04 | 08:08:00-04 - 08:08:00-04 | @ 5 mons 12 hours | 20:08:00-04 | 20:08:00-04 - 08:08:00-04 | @ 6 years | 08:08:00-04 | 08:08:00-04 - 08:08:00-04 | @ 34 years | 08:08:00-04 | 08:08:00-04 - 07:07:00-08 | @ 14 secs ago | 07:06:46-08 | 07:07:14-08 - 07:07:00-08 | @ 1 min | 07:08:00-08 | 07:06:00-08 - 07:07:00-08 | @ 5 hours | 12:07:00-08 | 02:07:00-08 - 07:07:00-08 | @ 1 day 2 hours 3 mins 4 secs | 09:10:04-08 | 05:03:56-08 - 07:07:00-08 | @ 10 days | 07:07:00-08 | 07:07:00-08 - 07:07:00-08 | @ 3 mons | 07:07:00-08 | 07:07:00-08 - 07:07:00-08 | @ 5 mons | 07:07:00-08 | 07:07:00-08 - 07:07:00-08 | @ 5 mons 12 hours | 19:07:00-08 | 19:07:00-08 - 07:07:00-08 | @ 6 years | 07:07:00-08 | 07:07:00-08 - 07:07:00-08 | @ 34 years | 07:07:00-08 | 07:07:00-08 - 11:59:00-07 | @ 14 secs ago | 11:58:46-07 | 11:59:14-07 - 11:59:00-07 | @ 1 min | 12:00:00-07 | 11:58:00-07 - 11:59:00-07 | @ 5 hours | 16:59:00-07 | 06:59:00-07 - 11:59:00-07 | @ 1 day 2 hours 3 mins 4 secs | 14:02:04-07 | 09:55:56-07 - 11:59:00-07 | @ 10 days | 11:59:00-07 | 11:59:00-07 - 11:59:00-07 | @ 3 mons | 11:59:00-07 | 11:59:00-07 - 11:59:00-07 | @ 5 mons | 11:59:00-07 | 11:59:00-07 - 11:59:00-07 | @ 5 mons 12 hours | 23:59:00-07 | 23:59:00-07 - 11:59:00-07 | @ 6 years | 11:59:00-07 | 11:59:00-07 - 11:59:00-07 | @ 34 years | 11:59:00-07 | 11:59:00-07 - 12:00:00-07 | @ 14 secs ago | 11:59:46-07 | 12:00:14-07 - 12:00:00-07 | @ 1 min | 12:01:00-07 | 11:59:00-07 - 12:00:00-07 | @ 5 hours | 17:00:00-07 | 07:00:00-07 - 12:00:00-07 | @ 1 day 2 hours 3 mins 4 secs | 14:03:04-07 | 09:56:56-07 - 12:00:00-07 | @ 10 days | 12:00:00-07 | 12:00:00-07 - 12:00:00-07 | @ 3 mons | 12:00:00-07 | 12:00:00-07 - 12:00:00-07 | @ 5 mons | 12:00:00-07 | 12:00:00-07 - 12:00:00-07 | @ 5 mons 12 hours | 00:00:00-07 | 00:00:00-07 - 12:00:00-07 | @ 6 years | 12:00:00-07 | 12:00:00-07 - 12:00:00-07 | @ 34 years | 12:00:00-07 | 12:00:00-07 - 12:01:00-07 | @ 14 secs ago | 12:00:46-07 | 12:01:14-07 - 12:01:00-07 | @ 1 min | 12:02:00-07 | 12:00:00-07 - 12:01:00-07 | @ 5 hours | 17:01:00-07 | 07:01:00-07 - 12:01:00-07 | @ 1 day 2 hours 3 mins 4 secs | 14:04:04-07 | 09:57:56-07 - 12:01:00-07 | @ 10 days | 12:01:00-07 | 12:01:00-07 - 12:01:00-07 | @ 3 mons | 12:01:00-07 | 12:01:00-07 - 12:01:00-07 | @ 5 mons | 12:01:00-07 | 12:01:00-07 - 12:01:00-07 | @ 5 mons 12 hours | 00:01:00-07 | 00:01:00-07 - 12:01:00-07 | @ 6 years | 12:01:00-07 | 12:01:00-07 - 12:01:00-07 | @ 34 years | 12:01:00-07 | 12:01:00-07 - 15:36:39-04 | @ 14 secs ago | 15:36:25-04 | 15:36:53-04 - 15:36:39-04 | @ 1 min | 15:37:39-04 | 15:35:39-04 - 15:36:39-04 | @ 5 hours | 20:36:39-04 | 10:36:39-04 - 15:36:39-04 | @ 1 day 2 hours 3 mins 4 secs | 17:39:43-04 | 13:33:35-04 - 15:36:39-04 | @ 10 days | 15:36:39-04 | 15:36:39-04 - 15:36:39-04 | @ 3 mons | 15:36:39-04 | 15:36:39-04 - 15:36:39-04 | @ 5 mons | 15:36:39-04 | 15:36:39-04 - 15:36:39-04 | @ 5 mons 12 hours | 03:36:39-04 | 03:36:39-04 - 15:36:39-04 | @ 6 years | 15:36:39-04 | 15:36:39-04 - 15:36:39-04 | @ 34 years | 15:36:39-04 | 15:36:39-04 - 15:36:39-05 | @ 14 secs ago | 15:36:25-05 | 15:36:53-05 - 15:36:39-05 | @ 1 min | 15:37:39-05 | 15:35:39-05 - 15:36:39-05 | @ 5 hours | 20:36:39-05 | 10:36:39-05 - 15:36:39-05 | @ 1 day 2 hours 3 mins 4 secs | 17:39:43-05 | 13:33:35-05 - 15:36:39-05 | @ 10 days | 15:36:39-05 | 15:36:39-05 - 15:36:39-05 | @ 3 mons | 15:36:39-05 | 15:36:39-05 - 15:36:39-05 | @ 5 mons | 15:36:39-05 | 15:36:39-05 - 15:36:39-05 | @ 5 mons 12 hours | 03:36:39-05 | 03:36:39-05 - 15:36:39-05 | @ 6 years | 15:36:39-05 | 15:36:39-05 - 15:36:39-05 | @ 34 years | 15:36:39-05 | 15:36:39-05 - 23:59:00-07 | @ 14 secs ago | 23:58:46-07 | 23:59:14-07 - 23:59:00-07 | @ 1 min | 00:00:00-07 | 23:58:00-07 - 23:59:00-07 | @ 5 hours | 04:59:00-07 | 18:59:00-07 - 23:59:00-07 | @ 1 day 2 hours 3 mins 4 secs | 02:02:04-07 | 21:55:56-07 - 23:59:00-07 | @ 10 days | 23:59:00-07 | 23:59:00-07 - 23:59:00-07 | @ 3 mons | 23:59:00-07 | 23:59:00-07 - 23:59:00-07 | @ 5 mons | 23:59:00-07 | 23:59:00-07 - 23:59:00-07 | @ 5 mons 12 hours | 11:59:00-07 | 11:59:00-07 - 23:59:00-07 | @ 6 years | 23:59:00-07 | 23:59:00-07 - 23:59:00-07 | @ 34 years | 23:59:00-07 | 23:59:00-07 - 23:59:59.99-07 | @ 14 secs ago | 23:59:45.99-07 | 00:00:13.99-07 - 23:59:59.99-07 | @ 1 min | 00:00:59.99-07 | 23:58:59.99-07 - 23:59:59.99-07 | @ 5 hours | 04:59:59.99-07 | 18:59:59.99-07 - 23:59:59.99-07 | @ 1 day 2 hours 3 mins 4 secs | 02:03:03.99-07 | 21:56:55.99-07 - 23:59:59.99-07 | @ 10 days | 23:59:59.99-07 | 23:59:59.99-07 - 23:59:59.99-07 | @ 3 mons | 23:59:59.99-07 | 23:59:59.99-07 - 23:59:59.99-07 | @ 5 mons | 23:59:59.99-07 | 23:59:59.99-07 - 23:59:59.99-07 | @ 5 mons 12 hours | 11:59:59.99-07 | 11:59:59.99-07 - 23:59:59.99-07 | @ 6 years | 23:59:59.99-07 | 23:59:59.99-07 - 23:59:59.99-07 | @ 34 years | 23:59:59.99-07 | 23:59:59.99-07 -(120 rows) - --- SQL9x OVERLAPS operator --- test with time zone -SELECT (timestamp with time zone '2000-11-27', timestamp with time zone '2000-11-28') - OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp with time zone '2000-11-26', timestamp with time zone '2000-11-27') - OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "False"; - False -------- - f -(1 row) - -SELECT (timestamp with time zone '2000-11-27', timestamp with time zone '2000-11-28') - OVERLAPS (timestamp with time zone '2000-11-27 12:00', interval '1 day') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp with time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp with time zone '2000-11-27 12:00', timestamp with time zone '2000-11-30') AS "False"; - False -------- - f -(1 row) - -SELECT (timestamp with time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp with time zone '2000-11-27', interval '12 hours') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp with time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp with time zone '2000-11-27 12:00', interval '12 hours') AS "False"; - False -------- - f -(1 row) - --- test without time zone -SELECT (timestamp without time zone '2000-11-27', timestamp without time zone '2000-11-28') - OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp without time zone '2000-11-26', timestamp without time zone '2000-11-27') - OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "False"; - False -------- - f -(1 row) - -SELECT (timestamp without time zone '2000-11-27', timestamp without time zone '2000-11-28') - OVERLAPS (timestamp without time zone '2000-11-27 12:00', interval '1 day') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp without time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp without time zone '2000-11-27 12:00', timestamp without time zone '2000-11-30') AS "False"; - False -------- - f -(1 row) - -SELECT (timestamp without time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp without time zone '2000-11-27', interval '12 hours') AS "True"; - True ------- - t -(1 row) - -SELECT (timestamp without time zone '2000-11-27', interval '12 hours') - OVERLAPS (timestamp without time zone '2000-11-27 12:00', interval '12 hours') AS "False"; - False -------- - f -(1 row) - --- test time and interval -SELECT (time '00:00', time '01:00') - OVERLAPS (time '00:30', time '01:30') AS "True"; - True ------- - t -(1 row) - -SELECT (time '00:00', interval '1 hour') - OVERLAPS (time '00:30', interval '1 hour') AS "True"; - True ------- - t -(1 row) - -SELECT (time '00:00', interval '1 hour') - OVERLAPS (time '01:30', interval '1 hour') AS "False"; - False -------- - f -(1 row) - --- SQL99 seems to want this to be false (and we conform to the spec). --- istm that this *should* return true, on the theory that time --- intervals can wrap around the day boundary - thomas 2001-09-25 -SELECT (time '00:00', interval '1 hour') - OVERLAPS (time '01:30', interval '1 day') AS "False"; - False -------- - f -(1 row) - -CREATE TABLE TEMP_TIMESTAMP (f1 timestamp with time zone); --- get some candidate input values -INSERT INTO TEMP_TIMESTAMP (f1) - SELECT d1 FROM TIMESTAMP_TBL - WHERE d1 BETWEEN '13-jun-1957' AND '1-jan-1997' - OR d1 BETWEEN '1-jan-1999' AND '1-jan-2010'; -SELECT '' AS "16", f1 AS "timestamp" - FROM TEMP_TIMESTAMP - ORDER BY "timestamp"; - 16 | timestamp -----+------------------------------ - | Thu Jan 01 00:00:00 1970 PST - | Wed Feb 28 17:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST - | Fri Dec 31 17:32:01 1999 PST - | Sat Jan 01 17:32:01 2000 PST - | Wed Mar 15 02:14:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST - | Wed Mar 15 12:14:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST - | Sun Dec 31 17:32:01 2000 PST - | Mon Jan 01 17:32:01 2001 PST - | Sat Sep 22 18:19:20 2001 PDT -(16 rows) - -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 + t.f1 AS plus - FROM TEMP_TIMESTAMP d, INTERVAL_TBL t - ORDER BY plus, "timestamp", "interval"; - 160 | timestamp | interval | plus ------+------------------------------+-------------------------------+------------------------------ - | Thu Jan 01 00:00:00 1970 PST | @ 14 secs ago | Wed Dec 31 23:59:46 1969 PST - | Thu Jan 01 00:00:00 1970 PST | @ 1 min | Thu Jan 01 00:01:00 1970 PST - | Thu Jan 01 00:00:00 1970 PST | @ 5 hours | Thu Jan 01 05:00:00 1970 PST - | Thu Jan 01 00:00:00 1970 PST | @ 1 day 2 hours 3 mins 4 secs | Fri Jan 02 02:03:04 1970 PST - | Thu Jan 01 00:00:00 1970 PST | @ 10 days | Sun Jan 11 00:00:00 1970 PST - | Thu Jan 01 00:00:00 1970 PST | @ 3 mons | Wed Apr 01 00:00:00 1970 PST - | Thu Jan 01 00:00:00 1970 PST | @ 5 mons | Mon Jun 01 00:00:00 1970 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 5 mons 12 hours | Mon Jun 01 12:00:00 1970 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 6 years | Thu Jan 01 00:00:00 1976 PST - | Wed Feb 28 17:32:01 1996 PST | @ 14 secs ago | Wed Feb 28 17:31:47 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 1 min | Wed Feb 28 17:33:01 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 5 hours | Wed Feb 28 22:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 14 secs ago | Thu Feb 29 17:31:47 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 1 min | Thu Feb 29 17:33:01 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Feb 29 19:35:05 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 5 hours | Thu Feb 29 22:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 14 secs ago | Fri Mar 01 17:31:47 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 1 min | Fri Mar 01 17:33:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Fri Mar 01 19:35:05 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 5 hours | Fri Mar 01 22:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Sat Mar 02 19:35:05 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 10 days | Sat Mar 09 17:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 10 days | Sun Mar 10 17:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 10 days | Mon Mar 11 17:32:01 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 3 mons | Tue May 28 17:32:01 1996 PDT - | Thu Feb 29 17:32:01 1996 PST | @ 3 mons | Wed May 29 17:32:01 1996 PDT - | Fri Mar 01 17:32:01 1996 PST | @ 3 mons | Sat Jun 01 17:32:01 1996 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 5 mons | Sun Jul 28 17:32:01 1996 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 5 mons 12 hours | Mon Jul 29 05:32:01 1996 PDT - | Thu Feb 29 17:32:01 1996 PST | @ 5 mons | Mon Jul 29 17:32:01 1996 PDT - | Thu Feb 29 17:32:01 1996 PST | @ 5 mons 12 hours | Tue Jul 30 05:32:01 1996 PDT - | Fri Mar 01 17:32:01 1996 PST | @ 5 mons | Thu Aug 01 17:32:01 1996 PDT - | Fri Mar 01 17:32:01 1996 PST | @ 5 mons 12 hours | Fri Aug 02 05:32:01 1996 PDT - | Mon Dec 30 17:32:01 1996 PST | @ 14 secs ago | Mon Dec 30 17:31:47 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 1 min | Mon Dec 30 17:33:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 5 hours | Mon Dec 30 22:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 14 secs ago | Tue Dec 31 17:31:47 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 1 min | Tue Dec 31 17:33:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Dec 31 19:35:05 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 5 hours | Tue Dec 31 22:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Wed Jan 01 19:35:05 1997 PST - | Mon Dec 30 17:32:01 1996 PST | @ 10 days | Thu Jan 09 17:32:01 1997 PST - | Tue Dec 31 17:32:01 1996 PST | @ 10 days | Fri Jan 10 17:32:01 1997 PST - | Mon Dec 30 17:32:01 1996 PST | @ 3 mons | Sun Mar 30 17:32:01 1997 PST - | Tue Dec 31 17:32:01 1996 PST | @ 3 mons | Mon Mar 31 17:32:01 1997 PST - | Mon Dec 30 17:32:01 1996 PST | @ 5 mons | Fri May 30 17:32:01 1997 PDT - | Mon Dec 30 17:32:01 1996 PST | @ 5 mons 12 hours | Sat May 31 05:32:01 1997 PDT - | Tue Dec 31 17:32:01 1996 PST | @ 5 mons | Sat May 31 17:32:01 1997 PDT - | Tue Dec 31 17:32:01 1996 PST | @ 5 mons 12 hours | Sun Jun 01 05:32:01 1997 PDT - | Fri Dec 31 17:32:01 1999 PST | @ 14 secs ago | Fri Dec 31 17:31:47 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 1 min | Fri Dec 31 17:33:01 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 5 hours | Fri Dec 31 22:32:01 1999 PST - | Sat Jan 01 17:32:01 2000 PST | @ 14 secs ago | Sat Jan 01 17:31:47 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 1 min | Sat Jan 01 17:33:01 2000 PST - | Fri Dec 31 17:32:01 1999 PST | @ 1 day 2 hours 3 mins 4 secs | Sat Jan 01 19:35:05 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 5 hours | Sat Jan 01 22:32:01 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Sun Jan 02 19:35:05 2000 PST - | Fri Dec 31 17:32:01 1999 PST | @ 10 days | Mon Jan 10 17:32:01 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 10 days | Tue Jan 11 17:32:01 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 14 secs ago | Wed Mar 15 02:13:51 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 1 min | Wed Mar 15 02:15:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 14 secs ago | Wed Mar 15 03:13:50 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 1 min | Wed Mar 15 03:15:04 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 5 hours | Wed Mar 15 07:14:05 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 14 secs ago | Wed Mar 15 08:13:47 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 5 hours | Wed Mar 15 08:14:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 1 min | Wed Mar 15 08:15:01 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 14 secs ago | Wed Mar 15 12:13:49 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 1 min | Wed Mar 15 12:15:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 14 secs ago | Wed Mar 15 13:13:48 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 5 hours | Wed Mar 15 13:14:01 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 1 min | Wed Mar 15 13:15:02 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 5 hours | Wed Mar 15 17:14:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 5 hours | Wed Mar 15 18:14:02 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Mar 16 04:17:09 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Mar 16 05:17:08 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Mar 16 10:17:05 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Mar 16 14:17:07 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Mar 16 15:17:06 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 10 days | Sat Mar 25 02:14:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 10 days | Sat Mar 25 03:14:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 10 days | Sat Mar 25 08:14:01 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 10 days | Sat Mar 25 12:14:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 10 days | Sat Mar 25 13:14:02 2000 PST - | Fri Dec 31 17:32:01 1999 PST | @ 3 mons | Fri Mar 31 17:32:01 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 3 mons | Sat Apr 01 17:32:01 2000 PST - | Fri Dec 31 17:32:01 1999 PST | @ 5 mons | Wed May 31 17:32:01 2000 PDT - | Fri Dec 31 17:32:01 1999 PST | @ 5 mons 12 hours | Thu Jun 01 05:32:01 2000 PDT - | Sat Jan 01 17:32:01 2000 PST | @ 5 mons | Thu Jun 01 17:32:01 2000 PDT - | Sat Jan 01 17:32:01 2000 PST | @ 5 mons 12 hours | Fri Jun 02 05:32:01 2000 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 3 mons | Thu Jun 15 02:14:05 2000 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 3 mons | Thu Jun 15 03:14:04 2000 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 3 mons | Thu Jun 15 08:14:01 2000 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 3 mons | Thu Jun 15 12:14:03 2000 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 3 mons | Thu Jun 15 13:14:02 2000 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 5 mons | Tue Aug 15 02:14:05 2000 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 5 mons | Tue Aug 15 03:14:04 2000 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 5 mons | Tue Aug 15 08:14:01 2000 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 5 mons | Tue Aug 15 12:14:03 2000 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 5 mons | Tue Aug 15 13:14:02 2000 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 5 mons 12 hours | Tue Aug 15 14:14:05 2000 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 5 mons 12 hours | Tue Aug 15 15:14:04 2000 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 5 mons 12 hours | Tue Aug 15 20:14:01 2000 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 5 mons 12 hours | Wed Aug 16 00:14:03 2000 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 5 mons 12 hours | Wed Aug 16 01:14:02 2000 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 14 secs ago | Sun Dec 31 17:31:47 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 1 min | Sun Dec 31 17:33:01 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 5 hours | Sun Dec 31 22:32:01 2000 PST - | Mon Jan 01 17:32:01 2001 PST | @ 14 secs ago | Mon Jan 01 17:31:47 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 1 min | Mon Jan 01 17:33:01 2001 PST - | Sun Dec 31 17:32:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Mon Jan 01 19:35:05 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 5 hours | Mon Jan 01 22:32:01 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Jan 02 19:35:05 2001 PST - | Sun Dec 31 17:32:01 2000 PST | @ 10 days | Wed Jan 10 17:32:01 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 10 days | Thu Jan 11 17:32:01 2001 PST - | Sun Dec 31 17:32:01 2000 PST | @ 3 mons | Sat Mar 31 17:32:01 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 3 mons | Sun Apr 01 17:32:01 2001 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 5 mons | Thu May 31 17:32:01 2001 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 5 mons 12 hours | Fri Jun 01 05:32:01 2001 PDT - | Mon Jan 01 17:32:01 2001 PST | @ 5 mons | Fri Jun 01 17:32:01 2001 PDT - | Mon Jan 01 17:32:01 2001 PST | @ 5 mons 12 hours | Sat Jun 02 05:32:01 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 14 secs ago | Sat Sep 22 18:19:06 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 1 min | Sat Sep 22 18:20:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 5 hours | Sat Sep 22 23:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 1 day 2 hours 3 mins 4 secs | Sun Sep 23 20:22:24 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 10 days | Tue Oct 02 18:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 3 mons | Sat Dec 22 18:19:20 2001 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 5 mons | Fri Feb 22 18:19:20 2002 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 5 mons 12 hours | Sat Feb 23 06:19:20 2002 PST - | Wed Feb 28 17:32:01 1996 PST | @ 6 years | Thu Feb 28 17:32:01 2002 PST - | Thu Feb 29 17:32:01 1996 PST | @ 6 years | Thu Feb 28 17:32:01 2002 PST - | Fri Mar 01 17:32:01 1996 PST | @ 6 years | Fri Mar 01 17:32:01 2002 PST - | Mon Dec 30 17:32:01 1996 PST | @ 6 years | Mon Dec 30 17:32:01 2002 PST - | Tue Dec 31 17:32:01 1996 PST | @ 6 years | Tue Dec 31 17:32:01 2002 PST - | Thu Jan 01 00:00:00 1970 PST | @ 34 years | Thu Jan 01 00:00:00 2004 PST - | Fri Dec 31 17:32:01 1999 PST | @ 6 years | Sat Dec 31 17:32:01 2005 PST - | Sat Jan 01 17:32:01 2000 PST | @ 6 years | Sun Jan 01 17:32:01 2006 PST - | Wed Mar 15 02:14:05 2000 PST | @ 6 years | Wed Mar 15 02:14:05 2006 PST - | Wed Mar 15 03:14:04 2000 PST | @ 6 years | Wed Mar 15 03:14:04 2006 PST - | Wed Mar 15 08:14:01 2000 PST | @ 6 years | Wed Mar 15 08:14:01 2006 PST - | Wed Mar 15 12:14:03 2000 PST | @ 6 years | Wed Mar 15 12:14:03 2006 PST - | Wed Mar 15 13:14:02 2000 PST | @ 6 years | Wed Mar 15 13:14:02 2006 PST - | Sun Dec 31 17:32:01 2000 PST | @ 6 years | Sun Dec 31 17:32:01 2006 PST - | Mon Jan 01 17:32:01 2001 PST | @ 6 years | Mon Jan 01 17:32:01 2007 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 6 years | Sat Sep 22 18:19:20 2007 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 34 years | Thu Feb 28 17:32:01 2030 PST - | Thu Feb 29 17:32:01 1996 PST | @ 34 years | Thu Feb 28 17:32:01 2030 PST - | Fri Mar 01 17:32:01 1996 PST | @ 34 years | Fri Mar 01 17:32:01 2030 PST - | Mon Dec 30 17:32:01 1996 PST | @ 34 years | Mon Dec 30 17:32:01 2030 PST - | Tue Dec 31 17:32:01 1996 PST | @ 34 years | Tue Dec 31 17:32:01 2030 PST - | Fri Dec 31 17:32:01 1999 PST | @ 34 years | Sat Dec 31 17:32:01 2033 PST - | Sat Jan 01 17:32:01 2000 PST | @ 34 years | Sun Jan 01 17:32:01 2034 PST - | Wed Mar 15 02:14:05 2000 PST | @ 34 years | Wed Mar 15 02:14:05 2034 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 34 years | Wed Mar 15 03:14:04 2034 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 34 years | Wed Mar 15 08:14:01 2034 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 34 years | Wed Mar 15 12:14:03 2034 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 34 years | Wed Mar 15 13:14:02 2034 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 34 years | Sun Dec 31 17:32:01 2034 PST - | Mon Jan 01 17:32:01 2001 PST | @ 34 years | Mon Jan 01 17:32:01 2035 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 34 years | Sat Sep 22 18:19:20 2035 PDT -(160 rows) - -SELECT '' AS "160", d.f1 AS "timestamp", t.f1 AS "interval", d.f1 - t.f1 AS minus - FROM TEMP_TIMESTAMP d, INTERVAL_TBL t - WHERE isfinite(d.f1) - ORDER BY minus, "timestamp", "interval"; - 160 | timestamp | interval | minus ------+------------------------------+-------------------------------+------------------------------ - | Thu Jan 01 00:00:00 1970 PST | @ 34 years | Wed Jan 01 00:00:00 1936 PST - | Wed Feb 28 17:32:01 1996 PST | @ 34 years | Wed Feb 28 17:32:01 1962 PST - | Thu Feb 29 17:32:01 1996 PST | @ 34 years | Wed Feb 28 17:32:01 1962 PST - | Fri Mar 01 17:32:01 1996 PST | @ 34 years | Thu Mar 01 17:32:01 1962 PST - | Mon Dec 30 17:32:01 1996 PST | @ 34 years | Sun Dec 30 17:32:01 1962 PST - | Tue Dec 31 17:32:01 1996 PST | @ 34 years | Mon Dec 31 17:32:01 1962 PST - | Thu Jan 01 00:00:00 1970 PST | @ 6 years | Wed Jan 01 00:00:00 1964 PST - | Fri Dec 31 17:32:01 1999 PST | @ 34 years | Fri Dec 31 17:32:01 1965 PST - | Sat Jan 01 17:32:01 2000 PST | @ 34 years | Sat Jan 01 17:32:01 1966 PST - | Wed Mar 15 02:14:05 2000 PST | @ 34 years | Tue Mar 15 02:14:05 1966 PST - | Wed Mar 15 03:14:04 2000 PST | @ 34 years | Tue Mar 15 03:14:04 1966 PST - | Wed Mar 15 08:14:01 2000 PST | @ 34 years | Tue Mar 15 08:14:01 1966 PST - | Wed Mar 15 12:14:03 2000 PST | @ 34 years | Tue Mar 15 12:14:03 1966 PST - | Wed Mar 15 13:14:02 2000 PST | @ 34 years | Tue Mar 15 13:14:02 1966 PST - | Sun Dec 31 17:32:01 2000 PST | @ 34 years | Sat Dec 31 17:32:01 1966 PST - | Mon Jan 01 17:32:01 2001 PST | @ 34 years | Sun Jan 01 17:32:01 1967 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 34 years | Fri Sep 22 18:19:20 1967 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 5 mons 12 hours | Thu Jul 31 12:00:00 1969 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 5 mons | Fri Aug 01 00:00:00 1969 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 3 mons | Wed Oct 01 00:00:00 1969 PDT - | Thu Jan 01 00:00:00 1970 PST | @ 10 days | Mon Dec 22 00:00:00 1969 PST - | Thu Jan 01 00:00:00 1970 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Dec 30 21:56:56 1969 PST - | Thu Jan 01 00:00:00 1970 PST | @ 5 hours | Wed Dec 31 19:00:00 1969 PST - | Thu Jan 01 00:00:00 1970 PST | @ 1 min | Wed Dec 31 23:59:00 1969 PST - | Thu Jan 01 00:00:00 1970 PST | @ 14 secs ago | Thu Jan 01 00:00:14 1970 PST - | Wed Feb 28 17:32:01 1996 PST | @ 6 years | Wed Feb 28 17:32:01 1990 PST - | Thu Feb 29 17:32:01 1996 PST | @ 6 years | Wed Feb 28 17:32:01 1990 PST - | Fri Mar 01 17:32:01 1996 PST | @ 6 years | Thu Mar 01 17:32:01 1990 PST - | Mon Dec 30 17:32:01 1996 PST | @ 6 years | Sun Dec 30 17:32:01 1990 PST - | Tue Dec 31 17:32:01 1996 PST | @ 6 years | Mon Dec 31 17:32:01 1990 PST - | Fri Dec 31 17:32:01 1999 PST | @ 6 years | Fri Dec 31 17:32:01 1993 PST - | Sat Jan 01 17:32:01 2000 PST | @ 6 years | Sat Jan 01 17:32:01 1994 PST - | Wed Mar 15 02:14:05 2000 PST | @ 6 years | Tue Mar 15 02:14:05 1994 PST - | Wed Mar 15 03:14:04 2000 PST | @ 6 years | Tue Mar 15 03:14:04 1994 PST - | Wed Mar 15 08:14:01 2000 PST | @ 6 years | Tue Mar 15 08:14:01 1994 PST - | Wed Mar 15 12:14:03 2000 PST | @ 6 years | Tue Mar 15 12:14:03 1994 PST - | Wed Mar 15 13:14:02 2000 PST | @ 6 years | Tue Mar 15 13:14:02 1994 PST - | Sun Dec 31 17:32:01 2000 PST | @ 6 years | Sat Dec 31 17:32:01 1994 PST - | Mon Jan 01 17:32:01 2001 PST | @ 6 years | Sun Jan 01 17:32:01 1995 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 6 years | Fri Sep 22 18:19:20 1995 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 5 mons 12 hours | Thu Sep 28 05:32:01 1995 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 5 mons | Thu Sep 28 17:32:01 1995 PDT - | Thu Feb 29 17:32:01 1996 PST | @ 5 mons 12 hours | Fri Sep 29 05:32:01 1995 PDT - | Thu Feb 29 17:32:01 1996 PST | @ 5 mons | Fri Sep 29 17:32:01 1995 PDT - | Fri Mar 01 17:32:01 1996 PST | @ 5 mons 12 hours | Sun Oct 01 05:32:01 1995 PDT - | Fri Mar 01 17:32:01 1996 PST | @ 5 mons | Sun Oct 01 17:32:01 1995 PDT - | Wed Feb 28 17:32:01 1996 PST | @ 3 mons | Tue Nov 28 17:32:01 1995 PST - | Thu Feb 29 17:32:01 1996 PST | @ 3 mons | Wed Nov 29 17:32:01 1995 PST - | Fri Mar 01 17:32:01 1996 PST | @ 3 mons | Fri Dec 01 17:32:01 1995 PST - | Wed Feb 28 17:32:01 1996 PST | @ 10 days | Sun Feb 18 17:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 10 days | Mon Feb 19 17:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 10 days | Tue Feb 20 17:32:01 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Feb 27 15:28:57 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 5 hours | Wed Feb 28 12:32:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Wed Feb 28 15:28:57 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 1 min | Wed Feb 28 17:31:01 1996 PST - | Wed Feb 28 17:32:01 1996 PST | @ 14 secs ago | Wed Feb 28 17:32:15 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 5 hours | Thu Feb 29 12:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Feb 29 15:28:57 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 1 min | Thu Feb 29 17:31:01 1996 PST - | Thu Feb 29 17:32:01 1996 PST | @ 14 secs ago | Thu Feb 29 17:32:15 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 5 hours | Fri Mar 01 12:32:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 1 min | Fri Mar 01 17:31:01 1996 PST - | Fri Mar 01 17:32:01 1996 PST | @ 14 secs ago | Fri Mar 01 17:32:15 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 5 mons 12 hours | Tue Jul 30 05:32:01 1996 PDT - | Mon Dec 30 17:32:01 1996 PST | @ 5 mons | Tue Jul 30 17:32:01 1996 PDT - | Tue Dec 31 17:32:01 1996 PST | @ 5 mons 12 hours | Wed Jul 31 05:32:01 1996 PDT - | Tue Dec 31 17:32:01 1996 PST | @ 5 mons | Wed Jul 31 17:32:01 1996 PDT - | Mon Dec 30 17:32:01 1996 PST | @ 3 mons | Mon Sep 30 17:32:01 1996 PDT - | Tue Dec 31 17:32:01 1996 PST | @ 3 mons | Mon Sep 30 17:32:01 1996 PDT - | Mon Dec 30 17:32:01 1996 PST | @ 10 days | Fri Dec 20 17:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 10 days | Sat Dec 21 17:32:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Sun Dec 29 15:28:57 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 5 hours | Mon Dec 30 12:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 1 day 2 hours 3 mins 4 secs | Mon Dec 30 15:28:57 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 1 min | Mon Dec 30 17:31:01 1996 PST - | Mon Dec 30 17:32:01 1996 PST | @ 14 secs ago | Mon Dec 30 17:32:15 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 5 hours | Tue Dec 31 12:32:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 1 min | Tue Dec 31 17:31:01 1996 PST - | Tue Dec 31 17:32:01 1996 PST | @ 14 secs ago | Tue Dec 31 17:32:15 1996 PST - | Fri Dec 31 17:32:01 1999 PST | @ 5 mons 12 hours | Sat Jul 31 05:32:01 1999 PDT - | Fri Dec 31 17:32:01 1999 PST | @ 5 mons | Sat Jul 31 17:32:01 1999 PDT - | Sat Jan 01 17:32:01 2000 PST | @ 5 mons 12 hours | Sun Aug 01 05:32:01 1999 PDT - | Sat Jan 01 17:32:01 2000 PST | @ 5 mons | Sun Aug 01 17:32:01 1999 PDT - | Fri Dec 31 17:32:01 1999 PST | @ 3 mons | Thu Sep 30 17:32:01 1999 PDT - | Sat Jan 01 17:32:01 2000 PST | @ 3 mons | Fri Oct 01 17:32:01 1999 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 5 mons 12 hours | Thu Oct 14 14:14:05 1999 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 5 mons 12 hours | Thu Oct 14 15:14:04 1999 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 5 mons 12 hours | Thu Oct 14 20:14:01 1999 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 5 mons 12 hours | Fri Oct 15 00:14:03 1999 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 5 mons 12 hours | Fri Oct 15 01:14:02 1999 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 5 mons | Fri Oct 15 02:14:05 1999 PDT - | Wed Mar 15 03:14:04 2000 PST | @ 5 mons | Fri Oct 15 03:14:04 1999 PDT - | Wed Mar 15 08:14:01 2000 PST | @ 5 mons | Fri Oct 15 08:14:01 1999 PDT - | Wed Mar 15 12:14:03 2000 PST | @ 5 mons | Fri Oct 15 12:14:03 1999 PDT - | Wed Mar 15 13:14:02 2000 PST | @ 5 mons | Fri Oct 15 13:14:02 1999 PDT - | Wed Mar 15 02:14:05 2000 PST | @ 3 mons | Wed Dec 15 02:14:05 1999 PST - | Wed Mar 15 03:14:04 2000 PST | @ 3 mons | Wed Dec 15 03:14:04 1999 PST - | Wed Mar 15 08:14:01 2000 PST | @ 3 mons | Wed Dec 15 08:14:01 1999 PST - | Wed Mar 15 12:14:03 2000 PST | @ 3 mons | Wed Dec 15 12:14:03 1999 PST - | Wed Mar 15 13:14:02 2000 PST | @ 3 mons | Wed Dec 15 13:14:02 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 10 days | Tue Dec 21 17:32:01 1999 PST - | Sat Jan 01 17:32:01 2000 PST | @ 10 days | Wed Dec 22 17:32:01 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 1 day 2 hours 3 mins 4 secs | Thu Dec 30 15:28:57 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 5 hours | Fri Dec 31 12:32:01 1999 PST - | Sat Jan 01 17:32:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Fri Dec 31 15:28:57 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 1 min | Fri Dec 31 17:31:01 1999 PST - | Fri Dec 31 17:32:01 1999 PST | @ 14 secs ago | Fri Dec 31 17:32:15 1999 PST - | Sat Jan 01 17:32:01 2000 PST | @ 5 hours | Sat Jan 01 12:32:01 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 1 min | Sat Jan 01 17:31:01 2000 PST - | Sat Jan 01 17:32:01 2000 PST | @ 14 secs ago | Sat Jan 01 17:32:15 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 10 days | Sun Mar 05 02:14:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 10 days | Sun Mar 05 03:14:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 10 days | Sun Mar 05 08:14:01 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 10 days | Sun Mar 05 12:14:03 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 10 days | Sun Mar 05 13:14:02 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Mar 14 00:11:01 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Mar 14 01:11:00 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Mar 14 06:10:57 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Mar 14 10:10:59 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Tue Mar 14 11:10:58 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 5 hours | Tue Mar 14 21:14:05 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 5 hours | Tue Mar 14 22:14:04 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 1 min | Wed Mar 15 02:13:05 2000 PST - | Wed Mar 15 02:14:05 2000 PST | @ 14 secs ago | Wed Mar 15 02:14:19 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 1 min | Wed Mar 15 03:13:04 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 5 hours | Wed Mar 15 03:14:01 2000 PST - | Wed Mar 15 03:14:04 2000 PST | @ 14 secs ago | Wed Mar 15 03:14:18 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 5 hours | Wed Mar 15 07:14:03 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 1 min | Wed Mar 15 08:13:01 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 5 hours | Wed Mar 15 08:14:02 2000 PST - | Wed Mar 15 08:14:01 2000 PST | @ 14 secs ago | Wed Mar 15 08:14:15 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 1 min | Wed Mar 15 12:13:03 2000 PST - | Wed Mar 15 12:14:03 2000 PST | @ 14 secs ago | Wed Mar 15 12:14:17 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 1 min | Wed Mar 15 13:13:02 2000 PST - | Wed Mar 15 13:14:02 2000 PST | @ 14 secs ago | Wed Mar 15 13:14:16 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 5 mons 12 hours | Mon Jul 31 05:32:01 2000 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 5 mons | Mon Jul 31 17:32:01 2000 PDT - | Mon Jan 01 17:32:01 2001 PST | @ 5 mons 12 hours | Tue Aug 01 05:32:01 2000 PDT - | Mon Jan 01 17:32:01 2001 PST | @ 5 mons | Tue Aug 01 17:32:01 2000 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 3 mons | Sat Sep 30 17:32:01 2000 PDT - | Mon Jan 01 17:32:01 2001 PST | @ 3 mons | Sun Oct 01 17:32:01 2000 PDT - | Sun Dec 31 17:32:01 2000 PST | @ 10 days | Thu Dec 21 17:32:01 2000 PST - | Mon Jan 01 17:32:01 2001 PST | @ 10 days | Fri Dec 22 17:32:01 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 1 day 2 hours 3 mins 4 secs | Sat Dec 30 15:28:57 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 5 hours | Sun Dec 31 12:32:01 2000 PST - | Mon Jan 01 17:32:01 2001 PST | @ 1 day 2 hours 3 mins 4 secs | Sun Dec 31 15:28:57 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 1 min | Sun Dec 31 17:31:01 2000 PST - | Sun Dec 31 17:32:01 2000 PST | @ 14 secs ago | Sun Dec 31 17:32:15 2000 PST - | Mon Jan 01 17:32:01 2001 PST | @ 5 hours | Mon Jan 01 12:32:01 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 1 min | Mon Jan 01 17:31:01 2001 PST - | Mon Jan 01 17:32:01 2001 PST | @ 14 secs ago | Mon Jan 01 17:32:15 2001 PST - | Sat Sep 22 18:19:20 2001 PDT | @ 5 mons 12 hours | Sun Apr 22 06:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 5 mons | Sun Apr 22 18:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 3 mons | Fri Jun 22 18:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 10 days | Wed Sep 12 18:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 1 day 2 hours 3 mins 4 secs | Fri Sep 21 16:16:16 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 5 hours | Sat Sep 22 13:19:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 1 min | Sat Sep 22 18:18:20 2001 PDT - | Sat Sep 22 18:19:20 2001 PDT | @ 14 secs ago | Sat Sep 22 18:19:34 2001 PDT -(160 rows) - -SELECT '' AS "16", d.f1 AS "timestamp", - timestamp with time zone '1980-01-06 00:00 GMT' AS gpstime_zero, - d.f1 - timestamp with time zone '1980-01-06 00:00 GMT' AS difference - FROM TEMP_TIMESTAMP d - ORDER BY difference; - 16 | timestamp | gpstime_zero | difference -----+------------------------------+------------------------------+------------------------------------- - | Thu Jan 01 00:00:00 1970 PST | Sat Jan 05 16:00:00 1980 PST | @ 3656 days 16 hours ago - | Wed Feb 28 17:32:01 1996 PST | Sat Jan 05 16:00:00 1980 PST | @ 5898 days 1 hour 32 mins 1 sec - | Thu Feb 29 17:32:01 1996 PST | Sat Jan 05 16:00:00 1980 PST | @ 5899 days 1 hour 32 mins 1 sec - | Fri Mar 01 17:32:01 1996 PST | Sat Jan 05 16:00:00 1980 PST | @ 5900 days 1 hour 32 mins 1 sec - | Mon Dec 30 17:32:01 1996 PST | Sat Jan 05 16:00:00 1980 PST | @ 6204 days 1 hour 32 mins 1 sec - | Tue Dec 31 17:32:01 1996 PST | Sat Jan 05 16:00:00 1980 PST | @ 6205 days 1 hour 32 mins 1 sec - | Fri Dec 31 17:32:01 1999 PST | Sat Jan 05 16:00:00 1980 PST | @ 7300 days 1 hour 32 mins 1 sec - | Sat Jan 01 17:32:01 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7301 days 1 hour 32 mins 1 sec - | Wed Mar 15 02:14:05 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7374 days 10 hours 14 mins 5 secs - | Wed Mar 15 03:14:04 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7374 days 11 hours 14 mins 4 secs - | Wed Mar 15 08:14:01 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7374 days 16 hours 14 mins 1 sec - | Wed Mar 15 12:14:03 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7374 days 20 hours 14 mins 3 secs - | Wed Mar 15 13:14:02 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7374 days 21 hours 14 mins 2 secs - | Sun Dec 31 17:32:01 2000 PST | Sat Jan 05 16:00:00 1980 PST | @ 7666 days 1 hour 32 mins 1 sec - | Mon Jan 01 17:32:01 2001 PST | Sat Jan 05 16:00:00 1980 PST | @ 7667 days 1 hour 32 mins 1 sec - | Sat Sep 22 18:19:20 2001 PDT | Sat Jan 05 16:00:00 1980 PST | @ 7931 days 1 hour 19 mins 20 secs -(16 rows) - -SELECT '' AS "226", d1.f1 AS timestamp1, d2.f1 AS timestamp2, d1.f1 - d2.f1 AS difference - FROM TEMP_TIMESTAMP d1, TEMP_TIMESTAMP d2 - ORDER BY timestamp1, timestamp2, difference; - 226 | timestamp1 | timestamp2 | difference ------+------------------------------+------------------------------+------------------------------------------- - | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 PST | @ 0 - | Thu Jan 01 00:00:00 1970 PST | Wed Feb 28 17:32:01 1996 PST | @ 9554 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Thu Feb 29 17:32:01 1996 PST | @ 9555 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Fri Mar 01 17:32:01 1996 PST | @ 9556 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Mon Dec 30 17:32:01 1996 PST | @ 9860 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Tue Dec 31 17:32:01 1996 PST | @ 9861 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Fri Dec 31 17:32:01 1999 PST | @ 10956 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Sat Jan 01 17:32:01 2000 PST | @ 10957 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Wed Mar 15 02:14:05 2000 PST | @ 11031 days 2 hours 14 mins 5 secs ago - | Thu Jan 01 00:00:00 1970 PST | Wed Mar 15 03:14:04 2000 PST | @ 11031 days 3 hours 14 mins 4 secs ago - | Thu Jan 01 00:00:00 1970 PST | Wed Mar 15 08:14:01 2000 PST | @ 11031 days 8 hours 14 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Wed Mar 15 12:14:03 2000 PST | @ 11031 days 12 hours 14 mins 3 secs ago - | Thu Jan 01 00:00:00 1970 PST | Wed Mar 15 13:14:02 2000 PST | @ 11031 days 13 hours 14 mins 2 secs ago - | Thu Jan 01 00:00:00 1970 PST | Sun Dec 31 17:32:01 2000 PST | @ 11322 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Mon Jan 01 17:32:01 2001 PST | @ 11323 days 17 hours 32 mins 1 sec ago - | Thu Jan 01 00:00:00 1970 PST | Sat Sep 22 18:19:20 2001 PDT | @ 11587 days 17 hours 19 mins 20 secs ago - | Wed Feb 28 17:32:01 1996 PST | Thu Jan 01 00:00:00 1970 PST | @ 9554 days 17 hours 32 mins 1 sec - | Wed Feb 28 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST | @ 0 - | Wed Feb 28 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST | @ 1 day ago - | Wed Feb 28 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST | @ 2 days ago - | Wed Feb 28 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST | @ 306 days ago - | Wed Feb 28 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST | @ 307 days ago - | Wed Feb 28 17:32:01 1996 PST | Fri Dec 31 17:32:01 1999 PST | @ 1402 days ago - | Wed Feb 28 17:32:01 1996 PST | Sat Jan 01 17:32:01 2000 PST | @ 1403 days ago - | Wed Feb 28 17:32:01 1996 PST | Wed Mar 15 02:14:05 2000 PST | @ 1476 days 8 hours 42 mins 4 secs ago - | Wed Feb 28 17:32:01 1996 PST | Wed Mar 15 03:14:04 2000 PST | @ 1476 days 9 hours 42 mins 3 secs ago - | Wed Feb 28 17:32:01 1996 PST | Wed Mar 15 08:14:01 2000 PST | @ 1476 days 14 hours 42 mins ago - | Wed Feb 28 17:32:01 1996 PST | Wed Mar 15 12:14:03 2000 PST | @ 1476 days 18 hours 42 mins 2 secs ago - | Wed Feb 28 17:32:01 1996 PST | Wed Mar 15 13:14:02 2000 PST | @ 1476 days 19 hours 42 mins 1 sec ago - | Wed Feb 28 17:32:01 1996 PST | Sun Dec 31 17:32:01 2000 PST | @ 1768 days ago - | Wed Feb 28 17:32:01 1996 PST | Mon Jan 01 17:32:01 2001 PST | @ 1769 days ago - | Wed Feb 28 17:32:01 1996 PST | Sat Sep 22 18:19:20 2001 PDT | @ 2032 days 23 hours 47 mins 19 secs ago - | Thu Feb 29 17:32:01 1996 PST | Thu Jan 01 00:00:00 1970 PST | @ 9555 days 17 hours 32 mins 1 sec - | Thu Feb 29 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST | @ 1 day - | Thu Feb 29 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST | @ 0 - | Thu Feb 29 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST | @ 1 day ago - | Thu Feb 29 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST | @ 305 days ago - | Thu Feb 29 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST | @ 306 days ago - | Thu Feb 29 17:32:01 1996 PST | Fri Dec 31 17:32:01 1999 PST | @ 1401 days ago - | Thu Feb 29 17:32:01 1996 PST | Sat Jan 01 17:32:01 2000 PST | @ 1402 days ago - | Thu Feb 29 17:32:01 1996 PST | Wed Mar 15 02:14:05 2000 PST | @ 1475 days 8 hours 42 mins 4 secs ago - | Thu Feb 29 17:32:01 1996 PST | Wed Mar 15 03:14:04 2000 PST | @ 1475 days 9 hours 42 mins 3 secs ago - | Thu Feb 29 17:32:01 1996 PST | Wed Mar 15 08:14:01 2000 PST | @ 1475 days 14 hours 42 mins ago - | Thu Feb 29 17:32:01 1996 PST | Wed Mar 15 12:14:03 2000 PST | @ 1475 days 18 hours 42 mins 2 secs ago - | Thu Feb 29 17:32:01 1996 PST | Wed Mar 15 13:14:02 2000 PST | @ 1475 days 19 hours 42 mins 1 sec ago - | Thu Feb 29 17:32:01 1996 PST | Sun Dec 31 17:32:01 2000 PST | @ 1767 days ago - | Thu Feb 29 17:32:01 1996 PST | Mon Jan 01 17:32:01 2001 PST | @ 1768 days ago - | Thu Feb 29 17:32:01 1996 PST | Sat Sep 22 18:19:20 2001 PDT | @ 2031 days 23 hours 47 mins 19 secs ago - | Fri Mar 01 17:32:01 1996 PST | Thu Jan 01 00:00:00 1970 PST | @ 9556 days 17 hours 32 mins 1 sec - | Fri Mar 01 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST | @ 2 days - | Fri Mar 01 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST | @ 1 day - | Fri Mar 01 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST | @ 0 - | Fri Mar 01 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST | @ 304 days ago - | Fri Mar 01 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST | @ 305 days ago - | Fri Mar 01 17:32:01 1996 PST | Fri Dec 31 17:32:01 1999 PST | @ 1400 days ago - | Fri Mar 01 17:32:01 1996 PST | Sat Jan 01 17:32:01 2000 PST | @ 1401 days ago - | Fri Mar 01 17:32:01 1996 PST | Wed Mar 15 02:14:05 2000 PST | @ 1474 days 8 hours 42 mins 4 secs ago - | Fri Mar 01 17:32:01 1996 PST | Wed Mar 15 03:14:04 2000 PST | @ 1474 days 9 hours 42 mins 3 secs ago - | Fri Mar 01 17:32:01 1996 PST | Wed Mar 15 08:14:01 2000 PST | @ 1474 days 14 hours 42 mins ago - | Fri Mar 01 17:32:01 1996 PST | Wed Mar 15 12:14:03 2000 PST | @ 1474 days 18 hours 42 mins 2 secs ago - | Fri Mar 01 17:32:01 1996 PST | Wed Mar 15 13:14:02 2000 PST | @ 1474 days 19 hours 42 mins 1 sec ago - | Fri Mar 01 17:32:01 1996 PST | Sun Dec 31 17:32:01 2000 PST | @ 1766 days ago - | Fri Mar 01 17:32:01 1996 PST | Mon Jan 01 17:32:01 2001 PST | @ 1767 days ago - | Fri Mar 01 17:32:01 1996 PST | Sat Sep 22 18:19:20 2001 PDT | @ 2030 days 23 hours 47 mins 19 secs ago - | Mon Dec 30 17:32:01 1996 PST | Thu Jan 01 00:00:00 1970 PST | @ 9860 days 17 hours 32 mins 1 sec - | Mon Dec 30 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST | @ 306 days - | Mon Dec 30 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST | @ 305 days - | Mon Dec 30 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST | @ 304 days - | Mon Dec 30 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST | @ 0 - | Mon Dec 30 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST | @ 1 day ago - | Mon Dec 30 17:32:01 1996 PST | Fri Dec 31 17:32:01 1999 PST | @ 1096 days ago - | Mon Dec 30 17:32:01 1996 PST | Sat Jan 01 17:32:01 2000 PST | @ 1097 days ago - | Mon Dec 30 17:32:01 1996 PST | Wed Mar 15 02:14:05 2000 PST | @ 1170 days 8 hours 42 mins 4 secs ago - | Mon Dec 30 17:32:01 1996 PST | Wed Mar 15 03:14:04 2000 PST | @ 1170 days 9 hours 42 mins 3 secs ago - | Mon Dec 30 17:32:01 1996 PST | Wed Mar 15 08:14:01 2000 PST | @ 1170 days 14 hours 42 mins ago - | Mon Dec 30 17:32:01 1996 PST | Wed Mar 15 12:14:03 2000 PST | @ 1170 days 18 hours 42 mins 2 secs ago - | Mon Dec 30 17:32:01 1996 PST | Wed Mar 15 13:14:02 2000 PST | @ 1170 days 19 hours 42 mins 1 sec ago - | Mon Dec 30 17:32:01 1996 PST | Sun Dec 31 17:32:01 2000 PST | @ 1462 days ago - | Mon Dec 30 17:32:01 1996 PST | Mon Jan 01 17:32:01 2001 PST | @ 1463 days ago - | Mon Dec 30 17:32:01 1996 PST | Sat Sep 22 18:19:20 2001 PDT | @ 1726 days 23 hours 47 mins 19 secs ago - | Tue Dec 31 17:32:01 1996 PST | Thu Jan 01 00:00:00 1970 PST | @ 9861 days 17 hours 32 mins 1 sec - | Tue Dec 31 17:32:01 1996 PST | Wed Feb 28 17:32:01 1996 PST | @ 307 days - | Tue Dec 31 17:32:01 1996 PST | Thu Feb 29 17:32:01 1996 PST | @ 306 days - | Tue Dec 31 17:32:01 1996 PST | Fri Mar 01 17:32:01 1996 PST | @ 305 days - | Tue Dec 31 17:32:01 1996 PST | Mon Dec 30 17:32:01 1996 PST | @ 1 day - | Tue Dec 31 17:32:01 1996 PST | Tue Dec 31 17:32:01 1996 PST | @ 0 - | Tue Dec 31 17:32:01 1996 PST | Fri Dec 31 17:32:01 1999 PST | @ 1095 days ago - | Tue Dec 31 17:32:01 1996 PST | Sat Jan 01 17:32:01 2000 PST | @ 1096 days ago - | Tue Dec 31 17:32:01 1996 PST | Wed Mar 15 02:14:05 2000 PST | @ 1169 days 8 hours 42 mins 4 secs ago - | Tue Dec 31 17:32:01 1996 PST | Wed Mar 15 03:14:04 2000 PST | @ 1169 days 9 hours 42 mins 3 secs ago - | Tue Dec 31 17:32:01 1996 PST | Wed Mar 15 08:14:01 2000 PST | @ 1169 days 14 hours 42 mins ago - | Tue Dec 31 17:32:01 1996 PST | Wed Mar 15 12:14:03 2000 PST | @ 1169 days 18 hours 42 mins 2 secs ago - | Tue Dec 31 17:32:01 1996 PST | Wed Mar 15 13:14:02 2000 PST | @ 1169 days 19 hours 42 mins 1 sec ago - | Tue Dec 31 17:32:01 1996 PST | Sun Dec 31 17:32:01 2000 PST | @ 1461 days ago - | Tue Dec 31 17:32:01 1996 PST | Mon Jan 01 17:32:01 2001 PST | @ 1462 days ago - | Tue Dec 31 17:32:01 1996 PST | Sat Sep 22 18:19:20 2001 PDT | @ 1725 days 23 hours 47 mins 19 secs ago - | Fri Dec 31 17:32:01 1999 PST | Thu Jan 01 00:00:00 1970 PST | @ 10956 days 17 hours 32 mins 1 sec - | Fri Dec 31 17:32:01 1999 PST | Wed Feb 28 17:32:01 1996 PST | @ 1402 days - | Fri Dec 31 17:32:01 1999 PST | Thu Feb 29 17:32:01 1996 PST | @ 1401 days - | Fri Dec 31 17:32:01 1999 PST | Fri Mar 01 17:32:01 1996 PST | @ 1400 days - | Fri Dec 31 17:32:01 1999 PST | Mon Dec 30 17:32:01 1996 PST | @ 1096 days - | Fri Dec 31 17:32:01 1999 PST | Tue Dec 31 17:32:01 1996 PST | @ 1095 days - | Fri Dec 31 17:32:01 1999 PST | Fri Dec 31 17:32:01 1999 PST | @ 0 - | Fri Dec 31 17:32:01 1999 PST | Sat Jan 01 17:32:01 2000 PST | @ 1 day ago - | Fri Dec 31 17:32:01 1999 PST | Wed Mar 15 02:14:05 2000 PST | @ 74 days 8 hours 42 mins 4 secs ago - | Fri Dec 31 17:32:01 1999 PST | Wed Mar 15 03:14:04 2000 PST | @ 74 days 9 hours 42 mins 3 secs ago - | Fri Dec 31 17:32:01 1999 PST | Wed Mar 15 08:14:01 2000 PST | @ 74 days 14 hours 42 mins ago - | Fri Dec 31 17:32:01 1999 PST | Wed Mar 15 12:14:03 2000 PST | @ 74 days 18 hours 42 mins 2 secs ago - | Fri Dec 31 17:32:01 1999 PST | Wed Mar 15 13:14:02 2000 PST | @ 74 days 19 hours 42 mins 1 sec ago - | Fri Dec 31 17:32:01 1999 PST | Sun Dec 31 17:32:01 2000 PST | @ 366 days ago - | Fri Dec 31 17:32:01 1999 PST | Mon Jan 01 17:32:01 2001 PST | @ 367 days ago - | Fri Dec 31 17:32:01 1999 PST | Sat Sep 22 18:19:20 2001 PDT | @ 630 days 23 hours 47 mins 19 secs ago - | Sat Jan 01 17:32:01 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 10957 days 17 hours 32 mins 1 sec - | Sat Jan 01 17:32:01 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1403 days - | Sat Jan 01 17:32:01 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1402 days - | Sat Jan 01 17:32:01 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1401 days - | Sat Jan 01 17:32:01 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1097 days - | Sat Jan 01 17:32:01 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1096 days - | Sat Jan 01 17:32:01 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 1 day - | Sat Jan 01 17:32:01 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 0 - | Sat Jan 01 17:32:01 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 73 days 8 hours 42 mins 4 secs ago - | Sat Jan 01 17:32:01 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 73 days 9 hours 42 mins 3 secs ago - | Sat Jan 01 17:32:01 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 73 days 14 hours 42 mins ago - | Sat Jan 01 17:32:01 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 73 days 18 hours 42 mins 2 secs ago - | Sat Jan 01 17:32:01 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 73 days 19 hours 42 mins 1 sec ago - | Sat Jan 01 17:32:01 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 365 days ago - | Sat Jan 01 17:32:01 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 366 days ago - | Sat Jan 01 17:32:01 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 629 days 23 hours 47 mins 19 secs ago - | Wed Mar 15 02:14:05 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11031 days 2 hours 14 mins 5 secs - | Wed Mar 15 02:14:05 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1476 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1475 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1474 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1170 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1169 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 74 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 73 days 8 hours 42 mins 4 secs - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 0 - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 59 mins 59 secs ago - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 5 hours 59 mins 56 secs ago - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 9 hours 59 mins 58 secs ago - | Wed Mar 15 02:14:05 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 10 hours 59 mins 57 secs ago - | Wed Mar 15 02:14:05 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 291 days 15 hours 17 mins 56 secs ago - | Wed Mar 15 02:14:05 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 292 days 15 hours 17 mins 56 secs ago - | Wed Mar 15 02:14:05 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 556 days 15 hours 5 mins 15 secs ago - | Wed Mar 15 03:14:04 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11031 days 3 hours 14 mins 4 secs - | Wed Mar 15 03:14:04 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1476 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1475 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1474 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1170 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1169 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 74 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 73 days 9 hours 42 mins 3 secs - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 59 mins 59 secs - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 0 - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 4 hours 59 mins 57 secs ago - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 8 hours 59 mins 59 secs ago - | Wed Mar 15 03:14:04 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 9 hours 59 mins 58 secs ago - | Wed Mar 15 03:14:04 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 291 days 14 hours 17 mins 57 secs ago - | Wed Mar 15 03:14:04 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 292 days 14 hours 17 mins 57 secs ago - | Wed Mar 15 03:14:04 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 556 days 14 hours 5 mins 16 secs ago - | Wed Mar 15 08:14:01 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11031 days 8 hours 14 mins 1 sec - | Wed Mar 15 08:14:01 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1476 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1475 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1474 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1170 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1169 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 74 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 73 days 14 hours 42 mins - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 5 hours 59 mins 56 secs - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 4 hours 59 mins 57 secs - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 0 - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 4 hours 2 secs ago - | Wed Mar 15 08:14:01 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 5 hours 1 sec ago - | Wed Mar 15 08:14:01 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 291 days 9 hours 18 mins ago - | Wed Mar 15 08:14:01 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 292 days 9 hours 18 mins ago - | Wed Mar 15 08:14:01 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 556 days 9 hours 5 mins 19 secs ago - | Wed Mar 15 12:14:03 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11031 days 12 hours 14 mins 3 secs - | Wed Mar 15 12:14:03 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1476 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1475 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1474 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1170 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1169 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 74 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 73 days 18 hours 42 mins 2 secs - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 9 hours 59 mins 58 secs - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 8 hours 59 mins 59 secs - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 4 hours 2 secs - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 0 - | Wed Mar 15 12:14:03 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 59 mins 59 secs ago - | Wed Mar 15 12:14:03 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 291 days 5 hours 17 mins 58 secs ago - | Wed Mar 15 12:14:03 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 292 days 5 hours 17 mins 58 secs ago - | Wed Mar 15 12:14:03 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 556 days 5 hours 5 mins 17 secs ago - | Wed Mar 15 13:14:02 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11031 days 13 hours 14 mins 2 secs - | Wed Mar 15 13:14:02 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1476 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1475 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1474 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1170 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1169 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 74 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 73 days 19 hours 42 mins 1 sec - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 10 hours 59 mins 57 secs - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 9 hours 59 mins 58 secs - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 5 hours 1 sec - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 59 mins 59 secs - | Wed Mar 15 13:14:02 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 0 - | Wed Mar 15 13:14:02 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 291 days 4 hours 17 mins 59 secs ago - | Wed Mar 15 13:14:02 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 292 days 4 hours 17 mins 59 secs ago - | Wed Mar 15 13:14:02 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 556 days 4 hours 5 mins 18 secs ago - | Sun Dec 31 17:32:01 2000 PST | Thu Jan 01 00:00:00 1970 PST | @ 11322 days 17 hours 32 mins 1 sec - | Sun Dec 31 17:32:01 2000 PST | Wed Feb 28 17:32:01 1996 PST | @ 1768 days - | Sun Dec 31 17:32:01 2000 PST | Thu Feb 29 17:32:01 1996 PST | @ 1767 days - | Sun Dec 31 17:32:01 2000 PST | Fri Mar 01 17:32:01 1996 PST | @ 1766 days - | Sun Dec 31 17:32:01 2000 PST | Mon Dec 30 17:32:01 1996 PST | @ 1462 days - | Sun Dec 31 17:32:01 2000 PST | Tue Dec 31 17:32:01 1996 PST | @ 1461 days - | Sun Dec 31 17:32:01 2000 PST | Fri Dec 31 17:32:01 1999 PST | @ 366 days - | Sun Dec 31 17:32:01 2000 PST | Sat Jan 01 17:32:01 2000 PST | @ 365 days - | Sun Dec 31 17:32:01 2000 PST | Wed Mar 15 02:14:05 2000 PST | @ 291 days 15 hours 17 mins 56 secs - | Sun Dec 31 17:32:01 2000 PST | Wed Mar 15 03:14:04 2000 PST | @ 291 days 14 hours 17 mins 57 secs - | Sun Dec 31 17:32:01 2000 PST | Wed Mar 15 08:14:01 2000 PST | @ 291 days 9 hours 18 mins - | Sun Dec 31 17:32:01 2000 PST | Wed Mar 15 12:14:03 2000 PST | @ 291 days 5 hours 17 mins 58 secs - | Sun Dec 31 17:32:01 2000 PST | Wed Mar 15 13:14:02 2000 PST | @ 291 days 4 hours 17 mins 59 secs - | Sun Dec 31 17:32:01 2000 PST | Sun Dec 31 17:32:01 2000 PST | @ 0 - | Sun Dec 31 17:32:01 2000 PST | Mon Jan 01 17:32:01 2001 PST | @ 1 day ago - | Sun Dec 31 17:32:01 2000 PST | Sat Sep 22 18:19:20 2001 PDT | @ 264 days 23 hours 47 mins 19 secs ago - | Mon Jan 01 17:32:01 2001 PST | Thu Jan 01 00:00:00 1970 PST | @ 11323 days 17 hours 32 mins 1 sec - | Mon Jan 01 17:32:01 2001 PST | Wed Feb 28 17:32:01 1996 PST | @ 1769 days - | Mon Jan 01 17:32:01 2001 PST | Thu Feb 29 17:32:01 1996 PST | @ 1768 days - | Mon Jan 01 17:32:01 2001 PST | Fri Mar 01 17:32:01 1996 PST | @ 1767 days - | Mon Jan 01 17:32:01 2001 PST | Mon Dec 30 17:32:01 1996 PST | @ 1463 days - | Mon Jan 01 17:32:01 2001 PST | Tue Dec 31 17:32:01 1996 PST | @ 1462 days - | Mon Jan 01 17:32:01 2001 PST | Fri Dec 31 17:32:01 1999 PST | @ 367 days - | Mon Jan 01 17:32:01 2001 PST | Sat Jan 01 17:32:01 2000 PST | @ 366 days - | Mon Jan 01 17:32:01 2001 PST | Wed Mar 15 02:14:05 2000 PST | @ 292 days 15 hours 17 mins 56 secs - | Mon Jan 01 17:32:01 2001 PST | Wed Mar 15 03:14:04 2000 PST | @ 292 days 14 hours 17 mins 57 secs - | Mon Jan 01 17:32:01 2001 PST | Wed Mar 15 08:14:01 2000 PST | @ 292 days 9 hours 18 mins - | Mon Jan 01 17:32:01 2001 PST | Wed Mar 15 12:14:03 2000 PST | @ 292 days 5 hours 17 mins 58 secs - | Mon Jan 01 17:32:01 2001 PST | Wed Mar 15 13:14:02 2000 PST | @ 292 days 4 hours 17 mins 59 secs - | Mon Jan 01 17:32:01 2001 PST | Sun Dec 31 17:32:01 2000 PST | @ 1 day - | Mon Jan 01 17:32:01 2001 PST | Mon Jan 01 17:32:01 2001 PST | @ 0 - | Mon Jan 01 17:32:01 2001 PST | Sat Sep 22 18:19:20 2001 PDT | @ 263 days 23 hours 47 mins 19 secs ago - | Sat Sep 22 18:19:20 2001 PDT | Thu Jan 01 00:00:00 1970 PST | @ 11587 days 17 hours 19 mins 20 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Feb 28 17:32:01 1996 PST | @ 2032 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Thu Feb 29 17:32:01 1996 PST | @ 2031 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Fri Mar 01 17:32:01 1996 PST | @ 2030 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Mon Dec 30 17:32:01 1996 PST | @ 1726 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Tue Dec 31 17:32:01 1996 PST | @ 1725 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Fri Dec 31 17:32:01 1999 PST | @ 630 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Sat Jan 01 17:32:01 2000 PST | @ 629 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Mar 15 02:14:05 2000 PST | @ 556 days 15 hours 5 mins 15 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Mar 15 03:14:04 2000 PST | @ 556 days 14 hours 5 mins 16 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Mar 15 08:14:01 2000 PST | @ 556 days 9 hours 5 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Mar 15 12:14:03 2000 PST | @ 556 days 5 hours 5 mins 17 secs - | Sat Sep 22 18:19:20 2001 PDT | Wed Mar 15 13:14:02 2000 PST | @ 556 days 4 hours 5 mins 18 secs - | Sat Sep 22 18:19:20 2001 PDT | Sun Dec 31 17:32:01 2000 PST | @ 264 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Mon Jan 01 17:32:01 2001 PST | @ 263 days 23 hours 47 mins 19 secs - | Sat Sep 22 18:19:20 2001 PDT | Sat Sep 22 18:19:20 2001 PDT | @ 0 -(256 rows) - --- --- Conversions --- -SELECT '' AS "16", f1 AS "timestamp", date(f1) AS date - FROM TEMP_TIMESTAMP - WHERE f1 <> timestamp 'now' - ORDER BY date, "timestamp"; - 16 | timestamp | date -----+------------------------------+------------ - | Thu Jan 01 00:00:00 1970 PST | 01-01-1970 - | Wed Feb 28 17:32:01 1996 PST | 02-28-1996 - | Thu Feb 29 17:32:01 1996 PST | 02-29-1996 - | Fri Mar 01 17:32:01 1996 PST | 03-01-1996 - | Mon Dec 30 17:32:01 1996 PST | 12-30-1996 - | Tue Dec 31 17:32:01 1996 PST | 12-31-1996 - | Fri Dec 31 17:32:01 1999 PST | 12-31-1999 - | Sat Jan 01 17:32:01 2000 PST | 01-01-2000 - | Wed Mar 15 02:14:05 2000 PST | 03-15-2000 - | Wed Mar 15 03:14:04 2000 PST | 03-15-2000 - | Wed Mar 15 08:14:01 2000 PST | 03-15-2000 - | Wed Mar 15 12:14:03 2000 PST | 03-15-2000 - | Wed Mar 15 13:14:02 2000 PST | 03-15-2000 - | Sun Dec 31 17:32:01 2000 PST | 12-31-2000 - | Mon Jan 01 17:32:01 2001 PST | 01-01-2001 - | Sat Sep 22 18:19:20 2001 PDT | 09-22-2001 -(16 rows) - -DROP TABLE TEMP_TIMESTAMP; --- --- Comparisons between datetime types, especially overflow cases ---- -SELECT '2202020-10-05'::date::timestamp; -- fail -ERROR: date out of range for timestamp -SELECT '2202020-10-05'::date > '2020-10-05'::timestamp as t; - t ---- - t -(1 row) - -SELECT '2020-10-05'::timestamp > '2202020-10-05'::date as f; - f ---- - f -(1 row) - -SELECT '2202020-10-05'::date::timestamptz; -- fail -ERROR: date out of range for timestamp -SELECT '2202020-10-05'::date > '2020-10-05'::timestamptz as t; - t ---- - t -(1 row) - -SELECT '2020-10-05'::timestamptz > '2202020-10-05'::date as f; - f ---- - f -(1 row) - --- This conversion may work depending on timezone -SELECT '4714-11-24 BC'::date::timestamptz; - timestamptz ---------------------------------- - Mon Nov 24 00:00:00 4714 PST BC -(1 row) - -SET TimeZone = 'UTC-2'; -SELECT '4714-11-24 BC'::date::timestamptz; -- fail -ERROR: date out of range for timestamp -SELECT '4714-11-24 BC'::date < '2020-10-05'::timestamptz as t; - t ---- - t -(1 row) - -SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::date as t; - t ---- - t -(1 row) - -SELECT '4714-11-24 BC'::timestamp < '2020-10-05'::timestamptz as t; - t ---- - t -(1 row) - -SELECT '2020-10-05'::timestamptz >= '4714-11-24 BC'::timestamp as t; - t ---- - t -(1 row) - -RESET TimeZone; --- --- Formats --- -SET DateStyle TO 'US,Postgres'; -SHOW DateStyle; - DateStyle ---------------- - Postgres, MDY -(1 row) - -SELECT '' AS "64", d1 AS us_postgres FROM TIMESTAMP_TBL; - 64 | us_postgres -----+----------------------------- - | -infinity - | infinity - | Thu Jan 01 00:00:00 1970 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:02 1997 - | Mon Feb 10 17:32:01.4 1997 - | Mon Feb 10 17:32:01.5 1997 - | Mon Feb 10 17:32:01.6 1997 - | Thu Jan 02 00:00:00 1997 - | Thu Jan 02 03:04:05 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Tue Jun 10 17:32:01 1997 - | Sat Sep 22 18:19:20 2001 - | Wed Mar 15 08:14:01 2000 - | Wed Mar 15 13:14:02 2000 - | Wed Mar 15 12:14:03 2000 - | Wed Mar 15 03:14:04 2000 - | Wed Mar 15 02:14:05 2000 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:00 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Tue Jun 10 18:32:01 1997 - | Mon Feb 10 17:32:01 1997 - | Tue Feb 11 17:32:01 1997 - | Wed Feb 12 17:32:01 1997 - | Thu Feb 13 17:32:01 1997 - | Fri Feb 14 17:32:01 1997 - | Sat Feb 15 17:32:01 1997 - | Sun Feb 16 17:32:01 1997 - | Tue Feb 16 17:32:01 0097 BC - | Sat Feb 16 17:32:01 0097 - | Thu Feb 16 17:32:01 0597 - | Tue Feb 16 17:32:01 1097 - | Sat Feb 16 17:32:01 1697 - | Thu Feb 16 17:32:01 1797 - | Tue Feb 16 17:32:01 1897 - | Sun Feb 16 17:32:01 1997 - | Sat Feb 16 17:32:01 2097 - | Wed Feb 28 17:32:01 1996 - | Thu Feb 29 17:32:01 1996 - | Fri Mar 01 17:32:01 1996 - | Mon Dec 30 17:32:01 1996 - | Tue Dec 31 17:32:01 1996 - | Wed Jan 01 17:32:01 1997 - | Fri Feb 28 17:32:01 1997 - | Sat Mar 01 17:32:01 1997 - | Tue Dec 30 17:32:01 1997 - | Wed Dec 31 17:32:01 1997 - | Fri Dec 31 17:32:01 1999 - | Sat Jan 01 17:32:01 2000 - | Sun Dec 31 17:32:01 2000 - | Mon Jan 01 17:32:01 2001 -(65 rows) - -SET DateStyle TO 'US,ISO'; -SELECT '' AS "64", d1 AS us_iso FROM TIMESTAMP_TBL; - 64 | us_iso -----+------------------------ - | -infinity - | infinity - | 1970-01-01 00:00:00 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:02 - | 1997-02-10 17:32:01.4 - | 1997-02-10 17:32:01.5 - | 1997-02-10 17:32:01.6 - | 1997-01-02 00:00:00 - | 1997-01-02 03:04:05 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-06-10 17:32:01 - | 2001-09-22 18:19:20 - | 2000-03-15 08:14:01 - | 2000-03-15 13:14:02 - | 2000-03-15 12:14:03 - | 2000-03-15 03:14:04 - | 2000-03-15 02:14:05 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:00 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-06-10 18:32:01 - | 1997-02-10 17:32:01 - | 1997-02-11 17:32:01 - | 1997-02-12 17:32:01 - | 1997-02-13 17:32:01 - | 1997-02-14 17:32:01 - | 1997-02-15 17:32:01 - | 1997-02-16 17:32:01 - | 0097-02-16 17:32:01 BC - | 0097-02-16 17:32:01 - | 0597-02-16 17:32:01 - | 1097-02-16 17:32:01 - | 1697-02-16 17:32:01 - | 1797-02-16 17:32:01 - | 1897-02-16 17:32:01 - | 1997-02-16 17:32:01 - | 2097-02-16 17:32:01 - | 1996-02-28 17:32:01 - | 1996-02-29 17:32:01 - | 1996-03-01 17:32:01 - | 1996-12-30 17:32:01 - | 1996-12-31 17:32:01 - | 1997-01-01 17:32:01 - | 1997-02-28 17:32:01 - | 1997-03-01 17:32:01 - | 1997-12-30 17:32:01 - | 1997-12-31 17:32:01 - | 1999-12-31 17:32:01 - | 2000-01-01 17:32:01 - | 2000-12-31 17:32:01 - | 2001-01-01 17:32:01 -(65 rows) - -SET DateStyle TO 'US,SQL'; -SHOW DateStyle; - DateStyle ------------ - SQL, MDY -(1 row) - -SELECT '' AS "64", d1 AS us_sql FROM TIMESTAMP_TBL; - 64 | us_sql -----+------------------------ - | -infinity - | infinity - | 01/01/1970 00:00:00 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:02 - | 02/10/1997 17:32:01.4 - | 02/10/1997 17:32:01.5 - | 02/10/1997 17:32:01.6 - | 01/02/1997 00:00:00 - | 01/02/1997 03:04:05 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 06/10/1997 17:32:01 - | 09/22/2001 18:19:20 - | 03/15/2000 08:14:01 - | 03/15/2000 13:14:02 - | 03/15/2000 12:14:03 - | 03/15/2000 03:14:04 - | 03/15/2000 02:14:05 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:00 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 02/10/1997 17:32:01 - | 06/10/1997 18:32:01 - | 02/10/1997 17:32:01 - | 02/11/1997 17:32:01 - | 02/12/1997 17:32:01 - | 02/13/1997 17:32:01 - | 02/14/1997 17:32:01 - | 02/15/1997 17:32:01 - | 02/16/1997 17:32:01 - | 02/16/0097 17:32:01 BC - | 02/16/0097 17:32:01 - | 02/16/0597 17:32:01 - | 02/16/1097 17:32:01 - | 02/16/1697 17:32:01 - | 02/16/1797 17:32:01 - | 02/16/1897 17:32:01 - | 02/16/1997 17:32:01 - | 02/16/2097 17:32:01 - | 02/28/1996 17:32:01 - | 02/29/1996 17:32:01 - | 03/01/1996 17:32:01 - | 12/30/1996 17:32:01 - | 12/31/1996 17:32:01 - | 01/01/1997 17:32:01 - | 02/28/1997 17:32:01 - | 03/01/1997 17:32:01 - | 12/30/1997 17:32:01 - | 12/31/1997 17:32:01 - | 12/31/1999 17:32:01 - | 01/01/2000 17:32:01 - | 12/31/2000 17:32:01 - | 01/01/2001 17:32:01 -(65 rows) - -SET DateStyle TO 'European,Postgres'; -SHOW DateStyle; - DateStyle ---------------- - Postgres, DMY -(1 row) - -INSERT INTO TIMESTAMP_TBL VALUES('13/06/1957'); -SELECT count(*) as one FROM TIMESTAMP_TBL WHERE d1 = 'Jun 13 1957'; - one ------ - 1 -(1 row) - -SELECT '' AS "65", d1 AS european_postgres FROM TIMESTAMP_TBL; - 65 | european_postgres -----+----------------------------- - | -infinity - | infinity - | Thu 01 Jan 00:00:00 1970 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:02 1997 - | Mon 10 Feb 17:32:01.4 1997 - | Mon 10 Feb 17:32:01.5 1997 - | Mon 10 Feb 17:32:01.6 1997 - | Thu 02 Jan 00:00:00 1997 - | Thu 02 Jan 03:04:05 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Tue 10 Jun 17:32:01 1997 - | Sat 22 Sep 18:19:20 2001 - | Wed 15 Mar 08:14:01 2000 - | Wed 15 Mar 13:14:02 2000 - | Wed 15 Mar 12:14:03 2000 - | Wed 15 Mar 03:14:04 2000 - | Wed 15 Mar 02:14:05 2000 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:00 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Tue 10 Jun 18:32:01 1997 - | Mon 10 Feb 17:32:01 1997 - | Tue 11 Feb 17:32:01 1997 - | Wed 12 Feb 17:32:01 1997 - | Thu 13 Feb 17:32:01 1997 - | Fri 14 Feb 17:32:01 1997 - | Sat 15 Feb 17:32:01 1997 - | Sun 16 Feb 17:32:01 1997 - | Tue 16 Feb 17:32:01 0097 BC - | Sat 16 Feb 17:32:01 0097 - | Thu 16 Feb 17:32:01 0597 - | Tue 16 Feb 17:32:01 1097 - | Sat 16 Feb 17:32:01 1697 - | Thu 16 Feb 17:32:01 1797 - | Tue 16 Feb 17:32:01 1897 - | Sun 16 Feb 17:32:01 1997 - | Sat 16 Feb 17:32:01 2097 - | Wed 28 Feb 17:32:01 1996 - | Thu 29 Feb 17:32:01 1996 - | Fri 01 Mar 17:32:01 1996 - | Mon 30 Dec 17:32:01 1996 - | Tue 31 Dec 17:32:01 1996 - | Wed 01 Jan 17:32:01 1997 - | Fri 28 Feb 17:32:01 1997 - | Sat 01 Mar 17:32:01 1997 - | Tue 30 Dec 17:32:01 1997 - | Wed 31 Dec 17:32:01 1997 - | Fri 31 Dec 17:32:01 1999 - | Sat 01 Jan 17:32:01 2000 - | Sun 31 Dec 17:32:01 2000 - | Mon 01 Jan 17:32:01 2001 - | Thu 13 Jun 00:00:00 1957 -(66 rows) - -SET DateStyle TO 'European,ISO'; -SHOW DateStyle; - DateStyle ------------ - ISO, DMY -(1 row) - -SELECT '' AS "65", d1 AS european_iso FROM TIMESTAMP_TBL; - 65 | european_iso -----+------------------------ - | -infinity - | infinity - | 1970-01-01 00:00:00 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:02 - | 1997-02-10 17:32:01.4 - | 1997-02-10 17:32:01.5 - | 1997-02-10 17:32:01.6 - | 1997-01-02 00:00:00 - | 1997-01-02 03:04:05 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-06-10 17:32:01 - | 2001-09-22 18:19:20 - | 2000-03-15 08:14:01 - | 2000-03-15 13:14:02 - | 2000-03-15 12:14:03 - | 2000-03-15 03:14:04 - | 2000-03-15 02:14:05 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:00 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-02-10 17:32:01 - | 1997-06-10 18:32:01 - | 1997-02-10 17:32:01 - | 1997-02-11 17:32:01 - | 1997-02-12 17:32:01 - | 1997-02-13 17:32:01 - | 1997-02-14 17:32:01 - | 1997-02-15 17:32:01 - | 1997-02-16 17:32:01 - | 0097-02-16 17:32:01 BC - | 0097-02-16 17:32:01 - | 0597-02-16 17:32:01 - | 1097-02-16 17:32:01 - | 1697-02-16 17:32:01 - | 1797-02-16 17:32:01 - | 1897-02-16 17:32:01 - | 1997-02-16 17:32:01 - | 2097-02-16 17:32:01 - | 1996-02-28 17:32:01 - | 1996-02-29 17:32:01 - | 1996-03-01 17:32:01 - | 1996-12-30 17:32:01 - | 1996-12-31 17:32:01 - | 1997-01-01 17:32:01 - | 1997-02-28 17:32:01 - | 1997-03-01 17:32:01 - | 1997-12-30 17:32:01 - | 1997-12-31 17:32:01 - | 1999-12-31 17:32:01 - | 2000-01-01 17:32:01 - | 2000-12-31 17:32:01 - | 2001-01-01 17:32:01 - | 1957-06-13 00:00:00 -(66 rows) - -SET DateStyle TO 'European,SQL'; -SHOW DateStyle; - DateStyle ------------ - SQL, DMY -(1 row) - -SELECT '' AS "65", d1 AS european_sql FROM TIMESTAMP_TBL; - 65 | european_sql -----+------------------------ - | -infinity - | infinity - | 01/01/1970 00:00:00 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:02 - | 10/02/1997 17:32:01.4 - | 10/02/1997 17:32:01.5 - | 10/02/1997 17:32:01.6 - | 02/01/1997 00:00:00 - | 02/01/1997 03:04:05 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/06/1997 17:32:01 - | 22/09/2001 18:19:20 - | 15/03/2000 08:14:01 - | 15/03/2000 13:14:02 - | 15/03/2000 12:14:03 - | 15/03/2000 03:14:04 - | 15/03/2000 02:14:05 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:00 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/02/1997 17:32:01 - | 10/06/1997 18:32:01 - | 10/02/1997 17:32:01 - | 11/02/1997 17:32:01 - | 12/02/1997 17:32:01 - | 13/02/1997 17:32:01 - | 14/02/1997 17:32:01 - | 15/02/1997 17:32:01 - | 16/02/1997 17:32:01 - | 16/02/0097 17:32:01 BC - | 16/02/0097 17:32:01 - | 16/02/0597 17:32:01 - | 16/02/1097 17:32:01 - | 16/02/1697 17:32:01 - | 16/02/1797 17:32:01 - | 16/02/1897 17:32:01 - | 16/02/1997 17:32:01 - | 16/02/2097 17:32:01 - | 28/02/1996 17:32:01 - | 29/02/1996 17:32:01 - | 01/03/1996 17:32:01 - | 30/12/1996 17:32:01 - | 31/12/1996 17:32:01 - | 01/01/1997 17:32:01 - | 28/02/1997 17:32:01 - | 01/03/1997 17:32:01 - | 30/12/1997 17:32:01 - | 31/12/1997 17:32:01 - | 31/12/1999 17:32:01 - | 01/01/2000 17:32:01 - | 31/12/2000 17:32:01 - | 01/01/2001 17:32:01 - | 13/06/1957 00:00:00 -(66 rows) - -RESET DateStyle; --- --- to_timestamp() --- -SELECT to_timestamp('0097/Feb/16 --> 08:14:30', 'YYYY/Mon/DD --> HH:MI:SS'); - to_timestamp ------------------------------- - Sat Feb 16 08:14:30 0097 PST -(1 row) - -SELECT to_timestamp('97/2/16 8:14:30', 'FMYYYY/FMMM/FMDD FMHH:FMMI:FMSS'); - to_timestamp ------------------------------- - Sat Feb 16 08:14:30 0097 PST -(1 row) - -SELECT to_timestamp('2011$03!18 23_38_15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Fri Mar 18 23:38:15 2011 PDT -(1 row) - -SELECT to_timestamp('1985 January 12', 'YYYY FMMonth DD'); - to_timestamp ------------------------------- - Sat Jan 12 00:00:00 1985 PST -(1 row) - -SELECT to_timestamp('1985 FMMonth 12', 'YYYY "FMMonth" DD'); - to_timestamp ------------------------------- - Sat Jan 12 00:00:00 1985 PST -(1 row) - -SELECT to_timestamp('1985 \ 12', 'YYYY \\ DD'); - to_timestamp ------------------------------- - Sat Jan 12 00:00:00 1985 PST -(1 row) - -SELECT to_timestamp('My birthday-> Year: 1976, Month: May, Day: 16', - '"My birthday-> Year:" YYYY, "Month:" FMMonth, "Day:" DD'); - to_timestamp ------------------------------- - Sun May 16 00:00:00 1976 PDT -(1 row) - -SELECT to_timestamp('1,582nd VIII 21', 'Y,YYYth FMRM DD'); - to_timestamp ------------------------------- - Sat Aug 21 00:00:00 1582 PST -(1 row) - -SELECT to_timestamp('15 "text between quote marks" 98 54 45', - E'HH24 "\\"text between quote marks\\"" YY MI SS'); - to_timestamp ------------------------------- - Thu Jan 01 15:54:45 1998 PST -(1 row) - -SELECT to_timestamp('05121445482000', 'MMDDHH24MISSYYYY'); - to_timestamp ------------------------------- - Fri May 12 14:45:48 2000 PDT -(1 row) - -SELECT to_timestamp('2000January09Sunday', 'YYYYFMMonthDDFMDay'); - to_timestamp ------------------------------- - Sun Jan 09 00:00:00 2000 PST -(1 row) - -SELECT to_timestamp('97/Feb/16', 'YYMonDD'); -ERROR: invalid value "/Feb/16" for "Mon" -DETAIL: The given value did not match any of the allowed values for this field. -SELECT to_timestamp('97/Feb/16', 'YY:Mon:DD'); - to_timestamp ------------------------------- - Sun Feb 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('97/Feb/16', 'FXYY:Mon:DD'); - to_timestamp ------------------------------- - Sun Feb 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('97/Feb/16', 'FXYY/Mon/DD'); - to_timestamp ------------------------------- - Sun Feb 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('19971116', 'YYYYMMDD'); - to_timestamp ------------------------------- - Sun Nov 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('20000-1116', 'YYYY-MMDD'); - to_timestamp -------------------------------- - Thu Nov 16 00:00:00 20000 PST -(1 row) - -SELECT to_timestamp('1997 AD 11 16', 'YYYY BC MM DD'); - to_timestamp ------------------------------- - Sun Nov 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('1997 BC 11 16', 'YYYY BC MM DD'); - to_timestamp ---------------------------------- - Tue Nov 16 00:00:00 1997 PST BC -(1 row) - -SELECT to_timestamp('1997 A.D. 11 16', 'YYYY B.C. MM DD'); - to_timestamp ------------------------------- - Sun Nov 16 00:00:00 1997 PST -(1 row) - -SELECT to_timestamp('1997 B.C. 11 16', 'YYYY B.C. MM DD'); - to_timestamp ---------------------------------- - Tue Nov 16 00:00:00 1997 PST BC -(1 row) - -SELECT to_timestamp('9-1116', 'Y-MMDD'); - to_timestamp ------------------------------- - Mon Nov 16 00:00:00 2009 PST -(1 row) - -SELECT to_timestamp('95-1116', 'YY-MMDD'); - to_timestamp ------------------------------- - Thu Nov 16 00:00:00 1995 PST -(1 row) - -SELECT to_timestamp('995-1116', 'YYY-MMDD'); - to_timestamp ------------------------------- - Thu Nov 16 00:00:00 1995 PST -(1 row) - -SELECT to_timestamp('2005426', 'YYYYWWD'); - to_timestamp ------------------------------- - Sat Oct 15 00:00:00 2005 PDT -(1 row) - -SELECT to_timestamp('2005300', 'YYYYDDD'); - to_timestamp ------------------------------- - Thu Oct 27 00:00:00 2005 PDT -(1 row) - -SELECT to_timestamp('2005527', 'IYYYIWID'); - to_timestamp ------------------------------- - Sun Jan 01 00:00:00 2006 PST -(1 row) - -SELECT to_timestamp('005527', 'IYYIWID'); - to_timestamp ------------------------------- - Sun Jan 01 00:00:00 2006 PST -(1 row) - -SELECT to_timestamp('05527', 'IYIWID'); - to_timestamp ------------------------------- - Sun Jan 01 00:00:00 2006 PST -(1 row) - -SELECT to_timestamp('5527', 'IIWID'); - to_timestamp ------------------------------- - Sun Jan 01 00:00:00 2006 PST -(1 row) - -SELECT to_timestamp('2005364', 'IYYYIDDD'); - to_timestamp ------------------------------- - Sun Jan 01 00:00:00 2006 PST -(1 row) - -SELECT to_timestamp('20050302', 'YYYYMMDD'); - to_timestamp ------------------------------- - Wed Mar 02 00:00:00 2005 PST -(1 row) - -SELECT to_timestamp('2005 03 02', 'YYYYMMDD'); - to_timestamp ------------------------------- - Wed Mar 02 00:00:00 2005 PST -(1 row) - -SELECT to_timestamp(' 2005 03 02', 'YYYYMMDD'); - to_timestamp ------------------------------- - Wed Mar 02 00:00:00 2005 PST -(1 row) - -SELECT to_timestamp(' 20050302', 'YYYYMMDD'); - to_timestamp ------------------------------- - Wed Mar 02 00:00:00 2005 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 AM', 'YYYY-MM-DD HH12:MI PM'); - to_timestamp ------------------------------- - Sun Dec 18 11:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 PM', 'YYYY-MM-DD HH12:MI PM'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 A.M.', 'YYYY-MM-DD HH12:MI P.M.'); - to_timestamp ------------------------------- - Sun Dec 18 11:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 P.M.', 'YYYY-MM-DD HH12:MI P.M.'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 +05', 'YYYY-MM-DD HH12:MI TZH'); - to_timestamp ------------------------------- - Sat Dec 17 22:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 -05', 'YYYY-MM-DD HH12:MI TZH'); - to_timestamp ------------------------------- - Sun Dec 18 08:38:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 +05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); - to_timestamp ------------------------------- - Sat Dec 17 22:18:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 -05:20', 'YYYY-MM-DD HH12:MI TZH:TZM'); - to_timestamp ------------------------------- - Sun Dec 18 08:58:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 20', 'YYYY-MM-DD HH12:MI TZM'); - to_timestamp ------------------------------- - Sun Dec 18 03:18:00 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 11:38 PST', 'YYYY-MM-DD HH12:MI TZ'); -- NYI -ERROR: formatting field "TZ" is only supported in to_char -SELECT to_timestamp('2018-11-02 12:34:56.025', 'YYYY-MM-DD HH24:MI:SS.MS'); - to_timestamp ----------------------------------- - Fri Nov 02 12:34:56.025 2018 PDT -(1 row) - -SELECT i, to_timestamp('2018-11-02 12:34:56', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+------------------------------ - 1 | Fri Nov 02 12:34:56 2018 PDT - 2 | Fri Nov 02 12:34:56 2018 PDT - 3 | Fri Nov 02 12:34:56 2018 PDT - 4 | Fri Nov 02 12:34:56 2018 PDT - 5 | Fri Nov 02 12:34:56 2018 PDT - 6 | Fri Nov 02 12:34:56 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.1', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+-------------------------------- - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.1 2018 PDT - 3 | Fri Nov 02 12:34:56.1 2018 PDT - 4 | Fri Nov 02 12:34:56.1 2018 PDT - 5 | Fri Nov 02 12:34:56.1 2018 PDT - 6 | Fri Nov 02 12:34:56.1 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.12', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+--------------------------------- - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.12 2018 PDT - 3 | Fri Nov 02 12:34:56.12 2018 PDT - 4 | Fri Nov 02 12:34:56.12 2018 PDT - 5 | Fri Nov 02 12:34:56.12 2018 PDT - 6 | Fri Nov 02 12:34:56.12 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.123', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+---------------------------------- - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.12 2018 PDT - 3 | Fri Nov 02 12:34:56.123 2018 PDT - 4 | Fri Nov 02 12:34:56.123 2018 PDT - 5 | Fri Nov 02 12:34:56.123 2018 PDT - 6 | Fri Nov 02 12:34:56.123 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.1234', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+----------------------------------- - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.12 2018 PDT - 3 | Fri Nov 02 12:34:56.123 2018 PDT - 4 | Fri Nov 02 12:34:56.1234 2018 PDT - 5 | Fri Nov 02 12:34:56.1234 2018 PDT - 6 | Fri Nov 02 12:34:56.1234 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.12345', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+------------------------------------ - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.12 2018 PDT - 3 | Fri Nov 02 12:34:56.123 2018 PDT - 4 | Fri Nov 02 12:34:56.1235 2018 PDT - 5 | Fri Nov 02 12:34:56.12345 2018 PDT - 6 | Fri Nov 02 12:34:56.12345 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.123456', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; - i | to_timestamp ----+------------------------------------- - 1 | Fri Nov 02 12:34:56.1 2018 PDT - 2 | Fri Nov 02 12:34:56.12 2018 PDT - 3 | Fri Nov 02 12:34:56.123 2018 PDT - 4 | Fri Nov 02 12:34:56.1235 2018 PDT - 5 | Fri Nov 02 12:34:56.12346 2018 PDT - 6 | Fri Nov 02 12:34:56.123456 2018 PDT -(6 rows) - -SELECT i, to_timestamp('2018-11-02 12:34:56.123456789', 'YYYY-MM-DD HH24:MI:SS.FF' || i) FROM generate_series(1, 6) i; -ERROR: date/time field value out of range: "2018-11-02 12:34:56.123456789" -SELECT to_date('1 4 1902', 'Q MM YYYY'); -- Q is ignored - to_date ------------- - 04-01-1902 -(1 row) - -SELECT to_date('3 4 21 01', 'W MM CC YY'); - to_date ------------- - 04-15-2001 -(1 row) - -SELECT to_date('2458872', 'J'); - to_date ------------- - 01-23-2020 -(1 row) - --- --- Check handling of BC dates --- -SELECT to_date('44-02-01 BC','YYYY-MM-DD BC'); - to_date ---------------- - 02-01-0044 BC -(1 row) - -SELECT to_date('-44-02-01','YYYY-MM-DD'); - to_date ---------------- - 02-01-0044 BC -(1 row) - -SELECT to_date('-44-02-01 BC','YYYY-MM-DD BC'); - to_date ------------- - 02-01-0044 -(1 row) - -SELECT to_timestamp('44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC'); - to_timestamp ---------------------------------- - Fri Feb 01 11:12:13 0044 PST BC -(1 row) - -SELECT to_timestamp('-44-02-01 11:12:13','YYYY-MM-DD HH24:MI:SS'); - to_timestamp ---------------------------------- - Fri Feb 01 11:12:13 0044 PST BC -(1 row) - -SELECT to_timestamp('-44-02-01 11:12:13 BC','YYYY-MM-DD HH24:MI:SS BC'); - to_timestamp ------------------------------- - Mon Feb 01 11:12:13 0044 PST -(1 row) - --- --- Check handling of multiple spaces in format and/or input --- -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2011-12-18 23:38:15', 'YYYY-MM-DD HH24:MI:SS'); - to_timestamp ------------------------------- - Sun Dec 18 23:38:15 2011 PST -(1 row) - -SELECT to_timestamp('2000+ JUN', 'YYYY/MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp(' 2000 +JUN', 'YYYY/MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp(' 2000 +JUN', 'YYYY//MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp('2000 +JUN', 'YYYY//MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp('2000 + JUN', 'YYYY MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp('2000 ++ JUN', 'YYYY MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); -ERROR: invalid value "+" for "MON" -DETAIL: The given value did not match any of the allowed values for this field. -SELECT to_timestamp('2000 + + JUN', 'YYYY MON'); - to_timestamp ------------------------------- - Thu Jun 01 00:00:00 2000 PDT -(1 row) - -SELECT to_timestamp('2000 -10', 'YYYY TZH'); - to_timestamp ------------------------------- - Sat Jan 01 02:00:00 2000 PST -(1 row) - -SELECT to_timestamp('2000 -10', 'YYYY TZH'); - to_timestamp ------------------------------- - Fri Dec 31 06:00:00 1999 PST -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYY MM DD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 12 18', 'YYYYxMMxDD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011x 12x 18', 'YYYYxMMxDD'); - to_date ------------- - 12-18-2011 -(1 row) - -SELECT to_date('2011 x12 x18', 'YYYYxMMxDD'); -ERROR: invalid value "x1" for "MM" -DETAIL: Value must be an integer. --- --- Check errors for some incorrect usages of to_timestamp() and to_date() --- --- Mixture of date conventions (ISO week and Gregorian): -SELECT to_timestamp('2005527', 'YYYYIWID'); -ERROR: invalid combination of date conventions -HINT: Do not mix Gregorian and ISO week date conventions in a formatting template. --- Insufficient characters in the source string: -SELECT to_timestamp('19971', 'YYYYMMDD'); -ERROR: source string too short for "MM" formatting field -DETAIL: Field requires 2 characters, but only 1 remain. -HINT: If your source string is not fixed-width, try using the "FM" modifier. --- Insufficient digit characters for a single node: -SELECT to_timestamp('19971)24', 'YYYYMMDD'); -ERROR: invalid value "1)" for "MM" -DETAIL: Field requires 2 characters, but only 1 could be parsed. -HINT: If your source string is not fixed-width, try using the "FM" modifier. --- We don't accept full-length day or month names if short form is specified: -SELECT to_timestamp('Friday 1-January-1999', 'DY DD MON YYYY'); -ERROR: invalid value "da" for "DD" -DETAIL: Value must be an integer. -SELECT to_timestamp('Fri 1-January-1999', 'DY DD MON YYYY'); -ERROR: invalid value "uary" for "YYYY" -DETAIL: Value must be an integer. -SELECT to_timestamp('Fri 1-Jan-1999', 'DY DD MON YYYY'); -- ok - to_timestamp ------------------------------- - Fri Jan 01 00:00:00 1999 PST -(1 row) - --- Value clobbering: -SELECT to_timestamp('1997-11-Jan-16', 'YYYY-MM-Mon-DD'); -ERROR: conflicting values for "Mon" field in formatting string -DETAIL: This value contradicts a previous setting for the same field type. --- Non-numeric input: -SELECT to_timestamp('199711xy', 'YYYYMMDD'); -ERROR: invalid value "xy" for "DD" -DETAIL: Value must be an integer. --- Input that doesn't fit in an int: -SELECT to_timestamp('10000000000', 'FMYYYY'); -ERROR: value for "YYYY" in source string is out of range -DETAIL: Value must be in the range -2147483648 to 2147483647. --- Out-of-range and not-quite-out-of-range fields: -SELECT to_timestamp('2016-06-13 25:00:00', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2016-06-13 25:00:00" -SELECT to_timestamp('2016-06-13 15:60:00', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2016-06-13 15:60:00" -SELECT to_timestamp('2016-06-13 15:50:60', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2016-06-13 15:50:60" -SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -- ok - to_timestamp ------------------------------- - Mon Jun 13 15:50:55 2016 PDT -(1 row) - -SELECT to_timestamp('2016-06-13 15:50:55', 'YYYY-MM-DD HH:MI:SS'); -ERROR: hour "15" is invalid for the 12-hour clock -HINT: Use the 24-hour clock, or give an hour between 1 and 12. -SELECT to_timestamp('2016-13-01 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2016-13-01 15:50:55" -SELECT to_timestamp('2016-02-30 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2016-02-30 15:50:55" -SELECT to_timestamp('2016-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -- ok - to_timestamp ------------------------------- - Mon Feb 29 15:50:55 2016 PST -(1 row) - -SELECT to_timestamp('2015-02-29 15:50:55', 'YYYY-MM-DD HH24:MI:SS'); -ERROR: date/time field value out of range: "2015-02-29 15:50:55" -SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSS'); -- ok - to_timestamp ------------------------------- - Wed Feb 11 23:53:20 2015 PST -(1 row) - -SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSS'); -ERROR: date/time field value out of range: "2015-02-11 86400" -SELECT to_timestamp('2015-02-11 86000', 'YYYY-MM-DD SSSSS'); -- ok - to_timestamp ------------------------------- - Wed Feb 11 23:53:20 2015 PST -(1 row) - -SELECT to_timestamp('2015-02-11 86400', 'YYYY-MM-DD SSSSS'); -ERROR: date/time field value out of range: "2015-02-11 86400" -SELECT to_date('2016-13-10', 'YYYY-MM-DD'); -ERROR: date/time field value out of range: "2016-13-10" -SELECT to_date('2016-02-30', 'YYYY-MM-DD'); -ERROR: date/time field value out of range: "2016-02-30" -SELECT to_date('2016-02-29', 'YYYY-MM-DD'); -- ok - to_date ------------- - 02-29-2016 -(1 row) - -SELECT to_date('2015-02-29', 'YYYY-MM-DD'); -ERROR: date/time field value out of range: "2015-02-29" -SELECT to_date('2015 365', 'YYYY DDD'); -- ok - to_date ------------- - 12-31-2015 -(1 row) - -SELECT to_date('2015 366', 'YYYY DDD'); -ERROR: date/time field value out of range: "2015 366" -SELECT to_date('2016 365', 'YYYY DDD'); -- ok - to_date ------------- - 12-30-2016 -(1 row) - -SELECT to_date('2016 366', 'YYYY DDD'); -- ok - to_date ------------- - 12-31-2016 -(1 row) - -SELECT to_date('2016 367', 'YYYY DDD'); -ERROR: date/time field value out of range: "2016 367" -SELECT to_date('0000-02-01','YYYY-MM-DD'); -- allowed, though it shouldn't be - to_date ---------------- - 02-01-0001 BC -(1 row) - --- --- Check behavior with SQL-style fixed-GMT-offset time zone (cf bug #8572) --- -SET TIME ZONE 'America/New_York'; -SET TIME ZONE '-1.5'; -SHOW TIME ZONE; - TimeZone ----------------- - <-01:30>+01:30 -(1 row) - -SELECT '2012-12-12 12:00'::timestamptz; - timestamptz ---------------------------------- - Wed Dec 12 12:00:00 2012 -01:30 -(1 row) - -SELECT '2012-12-12 12:00 America/New_York'::timestamptz; - timestamptz ---------------------------------- - Wed Dec 12 15:30:00 2012 -01:30 -(1 row) - -SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD HH:MI:SS TZ'); - to_char ----------------------------- - 2012-12-12 12:00:00 -01:30 -(1 row) - -SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSS'); - to_char ------------------- - 2012-12-12 43200 -(1 row) - -SELECT to_char('2012-12-12 12:00'::timestamptz, 'YYYY-MM-DD SSSSS'); - to_char ------------------- - 2012-12-12 43200 -(1 row) - -RESET TIME ZONE; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/type_sanity.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/type_sanity.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/type_sanity.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/type_sanity.out 2022-02-13 01:12:02.728814777 +0100 @@ -145,489 +145,8 @@ FROM pg_type t WHERE t.typarray = proargtypes[array_length(proargtypes, 1)-1]) END != provariadic; - oid | provariadic | proargtypes ------+-------------+------------- -(0 rows) - --- Check that all and only those functions with a variadic type have --- a variadic argument. -SELECT oid::regprocedure, proargmodes, provariadic -FROM pg_proc -WHERE (proargmodes IS NOT NULL AND 'v' = any(proargmodes)) - IS DISTINCT FROM - (provariadic != 0); - oid | proargmodes | provariadic ------+-------------+------------- -(0 rows) - --- As of 8.0, this check finds refcursor, which is borrowing --- other types' I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT - (p1.typelem != 0 AND p1.typlen < 0) AND NOT - (p2.prorettype = p1.oid AND NOT p2.proretset) -ORDER BY 1; - oid | typname | oid | proname -------+-----------+-----+--------- - 1790 | refcursor | 46 | textin -(1 row) - --- Varlena array types will point to array_in --- Exception as of 8.1: int2vector and oidvector have their own I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typinput = p2.oid AND - (p1.typelem != 0 AND p1.typlen < 0) AND NOT - (p2.oid = 'array_in'::regproc) -ORDER BY 1; - oid | typname | oid | proname ------+------------+-----+-------------- - 22 | int2vector | 40 | int2vectorin - 30 | oidvector | 54 | oidvectorin -(2 rows) - --- typinput routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typinput = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Composites, domains, enums, ranges should all use the same input routines -SELECT DISTINCT typtype, typinput -FROM pg_type AS p1 -WHERE p1.typtype not in ('b', 'p') -ORDER BY 1; - typtype | typinput ----------+----------- - c | record_in - d | domain_in - e | enum_in - r | range_in -(4 rows) - --- Check for bogus typoutput routines --- As of 8.0, this check finds refcursor, which is borrowing --- other types' I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT - (p2.pronargs = 1 AND - (p2.proargtypes[0] = p1.oid OR - (p2.oid = 'array_out'::regproc AND - p1.typelem != 0 AND p1.typlen = -1))) -ORDER BY 1; - oid | typname | oid | proname -------+-----------+-----+--------- - 1790 | refcursor | 47 | textout -(1 row) - -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typoutput = p2.oid AND NOT - (p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- typoutput routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typoutput = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Composites, enums, ranges should all use the same output routines -SELECT DISTINCT typtype, typoutput -FROM pg_type AS p1 -WHERE p1.typtype not in ('b', 'd', 'p') -ORDER BY 1; - typtype | typoutput ----------+------------ - c | record_out - e | enum_out - r | range_out -(3 rows) - --- Domains should have same typoutput as their base types -SELECT p1.oid, p1.typname, p2.oid, p2.typname -FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid -WHERE p1.typtype = 'd' AND p1.typoutput IS DISTINCT FROM p2.typoutput; - oid | typname | oid | typname ------+---------+-----+--------- -(0 rows) - --- Check for bogus typreceive routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typreceive = p2.oid AND NOT - ((p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype) OR - (p2.pronargs = 2 AND p2.proargtypes[0] = 'internal'::regtype AND - p2.proargtypes[1] = 'oid'::regtype) OR - (p2.pronargs = 3 AND p2.proargtypes[0] = 'internal'::regtype AND - p2.proargtypes[1] = 'oid'::regtype AND - p2.proargtypes[2] = 'int4'::regtype)); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- As of 7.4, this check finds refcursor, which is borrowing --- other types' I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT - (p1.typelem != 0 AND p1.typlen < 0) AND NOT - (p2.prorettype = p1.oid AND NOT p2.proretset) -ORDER BY 1; - oid | typname | oid | proname -------+-----------+------+---------- - 1790 | refcursor | 2414 | textrecv -(1 row) - --- Varlena array types will point to array_recv --- Exception as of 8.1: int2vector and oidvector have their own I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typreceive = p2.oid AND - (p1.typelem != 0 AND p1.typlen < 0) AND NOT - (p2.oid = 'array_recv'::regproc) -ORDER BY 1; - oid | typname | oid | proname ------+------------+------+---------------- - 22 | int2vector | 2410 | int2vectorrecv - 30 | oidvector | 2420 | oidvectorrecv -(2 rows) - --- Suspicious if typreceive doesn't take same number of args as typinput -SELECT p1.oid, p1.typname, p2.oid, p2.proname, p3.oid, p3.proname -FROM pg_type AS p1, pg_proc AS p2, pg_proc AS p3 -WHERE p1.typinput = p2.oid AND p1.typreceive = p3.oid AND - p2.pronargs != p3.pronargs; - oid | typname | oid | proname | oid | proname ------+---------+-----+---------+-----+--------- -(0 rows) - --- typreceive routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typreceive = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Composites, domains, enums, ranges should all use the same receive routines -SELECT DISTINCT typtype, typreceive -FROM pg_type AS p1 -WHERE p1.typtype not in ('b', 'p') -ORDER BY 1; - typtype | typreceive ----------+------------- - c | record_recv - d | domain_recv - e | enum_recv - r | range_recv -(4 rows) - --- Check for bogus typsend routines --- As of 7.4, this check finds refcursor, which is borrowing --- other types' I/O routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT - (p2.pronargs = 1 AND - (p2.proargtypes[0] = p1.oid OR - (p2.oid = 'array_send'::regproc AND - p1.typelem != 0 AND p1.typlen = -1))) -ORDER BY 1; - oid | typname | oid | proname -------+-----------+------+---------- - 1790 | refcursor | 2415 | textsend -(1 row) - -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typsend = p2.oid AND NOT - (p2.prorettype = 'bytea'::regtype AND NOT p2.proretset); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- typsend routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typsend = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Composites, enums, ranges should all use the same send routines -SELECT DISTINCT typtype, typsend -FROM pg_type AS p1 -WHERE p1.typtype not in ('b', 'd', 'p') -ORDER BY 1; - typtype | typsend ----------+------------- - c | record_send - e | enum_send - r | range_send -(3 rows) - --- Domains should have same typsend as their base types -SELECT p1.oid, p1.typname, p2.oid, p2.typname -FROM pg_type AS p1 LEFT JOIN pg_type AS p2 ON p1.typbasetype = p2.oid -WHERE p1.typtype = 'd' AND p1.typsend IS DISTINCT FROM p2.typsend; - oid | typname | oid | typname ------+---------+-----+--------- -(0 rows) - --- Check for bogus typmodin routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typmodin = p2.oid AND NOT - (p2.pronargs = 1 AND - p2.proargtypes[0] = 'cstring[]'::regtype AND - p2.prorettype = 'int4'::regtype AND NOT p2.proretset); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- typmodin routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typmodin = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Check for bogus typmodout routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typmodout = p2.oid AND NOT - (p2.pronargs = 1 AND - p2.proargtypes[0] = 'int4'::regtype AND - p2.prorettype = 'cstring'::regtype AND NOT p2.proretset); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- typmodout routines should not be volatile -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typmodout = p2.oid AND p2.provolatile NOT IN ('i', 's'); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- Array types should have same typmodin/out as their element types -SELECT p1.oid, p1.typname, p2.oid, p2.typname -FROM pg_type AS p1, pg_type AS p2 -WHERE p1.typelem = p2.oid AND NOT - (p1.typmodin = p2.typmodin AND p1.typmodout = p2.typmodout); - oid | typname | oid | typname ------+---------+-----+--------- -(0 rows) - --- Array types should have same typdelim as their element types -SELECT p1.oid, p1.typname, p2.oid, p2.typname -FROM pg_type AS p1, pg_type AS p2 -WHERE p1.typarray = p2.oid AND NOT (p1.typdelim = p2.typdelim); - oid | typname | oid | typname ------+---------+-----+--------- -(0 rows) - --- Look for array types whose typalign isn't sufficient -SELECT p1.oid, p1.typname, p1.typalign, p2.typname, p2.typalign -FROM pg_type AS p1, pg_type AS p2 -WHERE p1.typarray = p2.oid AND - p2.typalign != (CASE WHEN p1.typalign = 'd' THEN 'd'::"char" - ELSE 'i'::"char" END); - oid | typname | typalign | typname | typalign ------+---------+----------+---------+---------- -(0 rows) - --- Check for bogus typanalyze routines -SELECT p1.oid, p1.typname, p2.oid, p2.proname -FROM pg_type AS p1, pg_proc AS p2 -WHERE p1.typanalyze = p2.oid AND NOT - (p2.pronargs = 1 AND - p2.proargtypes[0] = 'internal'::regtype AND - p2.prorettype = 'bool'::regtype AND NOT p2.proretset); - oid | typname | oid | proname ------+---------+-----+--------- -(0 rows) - --- there does not seem to be a reason to care about volatility of typanalyze --- domains inherit their base type's typanalyze -SELECT d.oid, d.typname, d.typanalyze, t.oid, t.typname, t.typanalyze -FROM pg_type d JOIN pg_type t ON d.typbasetype = t.oid -WHERE d.typanalyze != t.typanalyze; - oid | typname | typanalyze | oid | typname | typanalyze ------+---------+------------+-----+---------+------------ -(0 rows) - --- range_typanalyze should be used for all and only range types --- (but exclude domains, which we checked above) -SELECT t.oid, t.typname, t.typanalyze -FROM pg_type t LEFT JOIN pg_range r on t.oid = r.rngtypid -WHERE t.typbasetype = 0 AND - (t.typanalyze = 'range_typanalyze'::regproc) != (r.rngtypid IS NOT NULL); - oid | typname | typanalyze ------+---------+------------ -(0 rows) - --- array_typanalyze should be used for all and only array types --- (but exclude domains, which we checked above) --- As of 9.2 this finds int2vector and oidvector, which are weird anyway -SELECT t.oid, t.typname, t.typanalyze -FROM pg_type t -WHERE t.typbasetype = 0 AND - (t.typanalyze = 'array_typanalyze'::regproc) != - (typelem != 0 AND typlen < 0) -ORDER BY 1; - oid | typname | typanalyze ------+------------+------------ - 22 | int2vector | - - 30 | oidvector | - -(2 rows) - --- **************** pg_class **************** --- Look for illegal values in pg_class fields -SELECT p1.oid, p1.relname -FROM pg_class as p1 -WHERE relkind NOT IN ('r', 'i', 'S', 't', 'v', 'm', 'c', 'f', 'p') OR - relpersistence NOT IN ('p', 'u', 't') OR - relreplident NOT IN ('d', 'n', 'f', 'i'); - oid | relname ------+--------- -(0 rows) - --- All tables and indexes should have an access method. -SELECT p1.oid, p1.relname -FROM pg_class as p1 -WHERE p1.relkind NOT IN ('S', 'v', 'f', 'c') and - p1.relam = 0; - oid | relname ------+--------- -(0 rows) - --- Conversely, sequences, views, types shouldn't have them -SELECT p1.oid, p1.relname -FROM pg_class as p1 -WHERE p1.relkind IN ('S', 'v', 'f', 'c') and - p1.relam != 0; - oid | relname ------+--------- -(0 rows) - --- Indexes should have AMs of type 'i' -SELECT pc.oid, pc.relname, pa.amname, pa.amtype -FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) -WHERE pc.relkind IN ('i') and - pa.amtype != 'i'; - oid | relname | amname | amtype ------+---------+--------+-------- -(0 rows) - --- Tables, matviews etc should have AMs of type 't' -SELECT pc.oid, pc.relname, pa.amname, pa.amtype -FROM pg_class as pc JOIN pg_am AS pa ON (pc.relam = pa.oid) -WHERE pc.relkind IN ('r', 't', 'm') and - pa.amtype != 't'; - oid | relname | amname | amtype ------+---------+--------+-------- -(0 rows) - --- **************** pg_attribute **************** --- Look for illegal values in pg_attribute fields -SELECT p1.attrelid, p1.attname -FROM pg_attribute as p1 -WHERE p1.attrelid = 0 OR p1.atttypid = 0 OR p1.attnum = 0 OR - p1.attcacheoff != -1 OR p1.attinhcount < 0 OR - (p1.attinhcount = 0 AND NOT p1.attislocal); - attrelid | attname -----------+--------- -(0 rows) - --- Cross-check attnum against parent relation -SELECT p1.attrelid, p1.attname, p2.oid, p2.relname -FROM pg_attribute AS p1, pg_class AS p2 -WHERE p1.attrelid = p2.oid AND p1.attnum > p2.relnatts; - attrelid | attname | oid | relname -----------+---------+-----+--------- -(0 rows) - --- Detect missing pg_attribute entries: should have as many non-system --- attributes as parent relation expects -SELECT p1.oid, p1.relname -FROM pg_class AS p1 -WHERE p1.relnatts != (SELECT count(*) FROM pg_attribute AS p2 - WHERE p2.attrelid = p1.oid AND p2.attnum > 0); - oid | relname ------+--------- -(0 rows) - --- Cross-check against pg_type entry --- NOTE: we allow attstorage to be 'plain' even when typstorage is not; --- this is mainly for toast tables. -SELECT p1.attrelid, p1.attname, p2.oid, p2.typname -FROM pg_attribute AS p1, pg_type AS p2 -WHERE p1.atttypid = p2.oid AND - (p1.attlen != p2.typlen OR - p1.attalign != p2.typalign OR - p1.attbyval != p2.typbyval OR - (p1.attstorage != p2.typstorage AND p1.attstorage != 'p')); - attrelid | attname | oid | typname -----------+---------+-----+--------- -(0 rows) - --- **************** pg_range **************** --- Look for illegal values in pg_range fields. -SELECT p1.rngtypid, p1.rngsubtype -FROM pg_range as p1 -WHERE p1.rngtypid = 0 OR p1.rngsubtype = 0 OR p1.rngsubopc = 0; - rngtypid | rngsubtype -----------+------------ -(0 rows) - --- rngcollation should be specified iff subtype is collatable -SELECT p1.rngtypid, p1.rngsubtype, p1.rngcollation, t.typcollation -FROM pg_range p1 JOIN pg_type t ON t.oid = p1.rngsubtype -WHERE (rngcollation = 0) != (typcollation = 0); - rngtypid | rngsubtype | rngcollation | typcollation -----------+------------+--------------+-------------- -(0 rows) - --- opclass had better be a btree opclass accepting the subtype. --- We must allow anyarray matches, cf opr_sanity's binary_coercible() -SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname -FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc -WHERE o.opcmethod != 403 OR - ((o.opcintype != p1.rngsubtype) AND NOT - (o.opcintype = 'pg_catalog.anyarray'::regtype AND - EXISTS(select 1 from pg_catalog.pg_type where - oid = p1.rngsubtype and typelem != 0 and typlen = -1))); - rngtypid | rngsubtype | opcmethod | opcname -----------+------------+-----------+--------- -(0 rows) - --- canonical function, if any, had better match the range type -SELECT p1.rngtypid, p1.rngsubtype, p.proname -FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngcanonical -WHERE pronargs != 1 OR proargtypes[0] != rngtypid OR prorettype != rngtypid; - rngtypid | rngsubtype | proname -----------+------------+--------- -(0 rows) - --- subdiff function, if any, had better match the subtype -SELECT p1.rngtypid, p1.rngsubtype, p.proname -FROM pg_range p1 JOIN pg_proc p ON p.oid = p1.rngsubdiff -WHERE pronargs != 2 - OR proargtypes[0] != rngsubtype OR proargtypes[1] != rngsubtype - OR prorettype != 'pg_catalog.float8'::regtype; - rngtypid | rngsubtype | proname -----------+------------+--------- -(0 rows) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/create_index.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/create_index.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/create_index.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/create_index.out 2022-02-13 01:12:08.402157685 +0100 @@ -901,1782 +901,8 @@ (1 row) SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno; - seqno | i | t --------+--------+-------- - 102 | {NULL} | {NULL} -(1 row) - -SELECT * FROM array_op_test WHERE i @> '{NULL}' ORDER BY seqno; - seqno | i | t --------+---+--- -(0 rows) - -SELECT * FROM array_op_test WHERE i && '{NULL}' ORDER BY seqno; - seqno | i | t --------+---+--- -(0 rows) - -SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno; - seqno | i | t --------+----+---- - 101 | {} | {} -(1 row) - -CREATE INDEX textarrayidx ON array_index_op_test USING gin (t); -explain (costs off) -SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno; - QUERY PLAN ------------------------------------------------------------- - Sort - Sort Key: seqno - -> Bitmap Heap Scan on array_index_op_test - Recheck Cond: (t @> '{AAAAAAAA72908}'::text[]) - -> Bitmap Index Scan on textarrayidx - Index Cond: (t @> '{AAAAAAAA72908}'::text[]) -(6 rows) - -SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908}' ORDER BY seqno; - seqno | i | t --------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------- - 22 | {11,6,56,62,53,30} | {AAAAAAAA72908} - 45 | {99,45} | {AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611} - 72 | {22,1,16,78,20,91,83} | {47735,AAAAAAA56483,AAAAAAAAAAAAA93788,AA42406,AAAAAAAAAAAAA73084,AAAAAAAA72908,AAAAAAAAAAAAAAAAAA61286,AAAAA66674,AAAAAAAAAAAAAAAAA50407} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} -(4 rows) - -SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908}' ORDER BY seqno; - seqno | i | t --------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------- - 22 | {11,6,56,62,53,30} | {AAAAAAAA72908} - 45 | {99,45} | {AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611} - 72 | {22,1,16,78,20,91,83} | {47735,AAAAAAA56483,AAAAAAAAAAAAA93788,AA42406,AAAAAAAAAAAAA73084,AAAAAAAA72908,AAAAAAAAAAAAAAAAAA61286,AAAAA66674,AAAAAAAAAAAAAAAAA50407} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} -(4 rows) - -SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAAAA646}' ORDER BY seqno; - seqno | i | t --------+------------------+-------------------------------------------------------------------- - 15 | {17,14,16,63,67} | {AA6416,AAAAAAAAAA646,AAAAA95309} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} - 96 | {23,97,43} | {AAAAAAAAAA646,A87088} -(3 rows) - -SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAAAA646}' ORDER BY seqno; - seqno | i | t --------+------------------+-------------------------------------------------------------------- - 15 | {17,14,16,63,67} | {AA6416,AAAAAAAAAA646,AAAAA95309} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} - 96 | {23,97,43} | {AAAAAAAAAA646,A87088} -(3 rows) - -SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; - seqno | i | t --------+------+-------------------------------------------------------------------- - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} -(1 row) - -SELECT * FROM array_index_op_test WHERE t && '{AAAAAAAA72908,AAAAAAAAAA646}' ORDER BY seqno; - seqno | i | t --------+-----------------------+-------------------------------------------------------------------------------------------------------------------------------------------- - 15 | {17,14,16,63,67} | {AA6416,AAAAAAAAAA646,AAAAA95309} - 22 | {11,6,56,62,53,30} | {AAAAAAAA72908} - 45 | {99,45} | {AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611} - 72 | {22,1,16,78,20,91,83} | {47735,AAAAAAA56483,AAAAAAAAAAAAA93788,AA42406,AAAAAAAAAAAAA73084,AAAAAAAA72908,AAAAAAAAAAAAAAAAAA61286,AAAAA66674,AAAAAAAAAAAAAAAAA50407} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} - 96 | {23,97,43} | {AAAAAAAAAA646,A87088} -(6 rows) - -SELECT * FROM array_index_op_test WHERE t <@ '{AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611}' ORDER BY seqno; - seqno | i | t --------+--------------------+----------------------------------------------------------------------------------------------------------- - 22 | {11,6,56,62,53,30} | {AAAAAAAA72908} - 45 | {99,45} | {AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611} - 101 | {} | {} -(3 rows) - -SELECT * FROM array_index_op_test WHERE t = '{AAAAAAAAAA646,A87088}' ORDER BY seqno; - seqno | i | t --------+------------+------------------------ - 96 | {23,97,43} | {AAAAAAAAAA646,A87088} -(1 row) - -SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno; - seqno | i | t --------+----+---- - 101 | {} | {} -(1 row) - -SELECT * FROM array_index_op_test WHERE t @> '{}' ORDER BY seqno; - seqno | i | t --------+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 1 | {92,75,71,52,64,83} | {AAAAAAAA44066,AAAAAA1059,AAAAAAAAAAA176,AAAAAAA48038} - 2 | {3,6} | {AAAAAA98232,AAAAAAAA79710,AAAAAAAAAAAAAAAAA69675,AAAAAAAAAAAAAAAA55798,AAAAAAAAA12793} - 3 | {37,64,95,43,3,41,13,30,11,43} | {AAAAAAAAAA48845,AAAAA75968,AAAAA95309,AAA54451,AAAAAAAAAA22292,AAAAAAA99836,A96617,AA17009,AAAAAAAAAAAAAA95246} - 4 | {71,39,99,55,33,75,45} | {AAAAAAAAA53663,AAAAAAAAAAAAAAA67062,AAAAAAAAAA64777,AAA99043,AAAAAAAAAAAAAAAAAAA91804,39557} - 5 | {50,42,77,50,4} | {AAAAAAAAAAAAAAAAA26540,AAAAAAA79710,AAAAAAAAAAAAAAAAAAA1205,AAAAAAAAAAA176,AAAAA95309,AAAAAAAAAAA46154,AAAAAA66777,AAAAAAAAA27249,AAAAAAAAAA64777,AAAAAAAAAAAAAAAAAAA70104} - 6 | {39,35,5,94,17,92,60,32} | {AAAAAAAAAAAAAAA35875,AAAAAAAAAAAAAAAA23657} - 7 | {12,51,88,64,8} | {AAAAAAAAAAAAAAAAAA12591,AAAAAAAAAAAAAAAAA50407,AAAAAAAAAAAA67946} - 8 | {60,84} | {AAAAAAA81898,AAAAAA1059,AAAAAAAAAAAA81511,AAAAA961,AAAAAAAAAAAAAAAA31334,AAAAA64741,AA6416,AAAAAAAAAAAAAAAAAA32918,AAAAAAAAAAAAAAAAA50407} - 9 | {56,52,35,27,80,44,81,22} | {AAAAAAAAAAAAAAA73034,AAAAAAAAAAAAA7929,AAAAAAA66161,AA88409,39557,A27153,AAAAAAAA9523,AAAAAAAAAAA99000} - 10 | {71,5,45} | {AAAAAAAAAAA21658,AAAAAAAAAAAA21089,AAA54451,AAAAAAAAAAAAAAAAAA54141,AAAAAAAAAAAAAA28620,AAAAAAAAAAA21658,AAAAAAAAAAA74076,AAAAAAAAA27249} - 11 | {41,86,74,48,22,74,47,50} | {AAAAAAAA9523,AAAAAAAAAAAA37562,AAAAAAAAAAAAAAAA14047,AAAAAAAAAAA46154,AAAA41702,AAAAAAAAAAAAAAAAA764,AAAAA62737,39557} - 12 | {17,99,18,52,91,72,0,43,96,23} | {AAAAA33250,AAAAAAAAAAAAAAAAAAA85420,AAAAAAAAAAA33576} - 13 | {3,52,34,23} | {AAAAAA98232,AAAA49534,AAAAAAAAAAA21658} - 14 | {78,57,19} | {AAAA8857,AAAAAAAAAAAAAAA73034,AAAAAAAA81587,AAAAAAAAAAAAAAA68526,AAAAA75968,AAAAAAAAAAAAAA65909,AAAAAAAAA10012,AAAAAAAAAAAAAA65909} - 15 | {17,14,16,63,67} | {AA6416,AAAAAAAAAA646,AAAAA95309} - 16 | {14,63,85,11} | {AAAAAA66777} - 17 | {7,10,81,85} | {AAAAAA43678,AAAAAAA12144,AAAAAAAAAAA50956,AAAAAAAAAAAAAAAAAAA15356} - 18 | {1} | {AAAAAAAAAAA33576,AAAAA95309,64261,AAA59323,AAAAAAAAAAAAAA95246,55847,AAAAAAAAAAAA67946,AAAAAAAAAAAAAAAAAA64374} - 19 | {52,82,17,74,23,46,69,51,75} | {AAAAAAAAAAAAA73084,AAAAA75968,AAAAAAAAAAAAAAAA14047,AAAAAAA80240,AAAAAAAAAAAAAAAAAAA1205,A68938} - 20 | {72,89,70,51,54,37,8,49,79} | {AAAAAA58494} - 21 | {2,8,65,10,5,79,43} | {AAAAAAAAAAAAAAAAA88852,AAAAAAAAAAAAAAAAAAA91804,AAAAA64669,AAAAAAAAAAAAAAAA1443,AAAAAAAAAAAAAAAA23657,AAAAA12179,AAAAAAAAAAAAAAAAA88852,AAAAAAAAAAAAAAAA31334,AAAAAAAAAAAAAAAA41303,AAAAAAAAAAAAAAAAAAA85420} - 22 | {11,6,56,62,53,30} | {AAAAAAAA72908} - 23 | {40,90,5,38,72,40,30,10,43,55} | {A6053,AAAAAAAAAAA6119,AA44673,AAAAAAAAAAAAAAAAA764,AA17009,AAAAA17383,AAAAA70514,AAAAA33250,AAAAA95309,AAAAAAAAAAAA37562} - 24 | {94,61,99,35,48} | {AAAAAAAAAAA50956,AAAAAAAAAAA15165,AAAA85070,AAAAAAAAAAAAAAA36627,AAAAA961,AAAAAAAAAA55219} - 25 | {31,1,10,11,27,79,38} | {AAAAAAAAAAAAAAAAAA59334,45449} - 26 | {71,10,9,69,75} | {47735,AAAAAAA21462,AAAAAAAAAAAAAAAAA6897,AAAAAAAAAAAAAAAAAAA91804,AAAAAAAAA72121,AAAAAAAAAAAAAAAAAAA1205,AAAAA41597,AAAA8857,AAAAAAAAAAAAAAAAAAA15356,AA17009} - 27 | {94} | {AA6416,A6053,AAAAAAA21462,AAAAAAA57334,AAAAAAAAAAAAAAAAAA12591,AA88409,AAAAAAAAAAAAA70254} - 28 | {14,33,6,34,14} | {AAAAAAAAAAAAAAA13198,AAAAAAAA69452,AAAAAAAAAAA82945,AAAAAAA12144,AAAAAAAAA72121,AAAAAAAAAA18601} - 29 | {39,21} | {AAAAAAAAAAAAAAAAA6897,AAAAAAAAAAAAAAAAAAA38885,AAAA85070,AAAAAAAAAAAAAAAAAAA70104,AAAAA66674,AAAAAAAAAAAAA62007,AAAAAAAA69452,AAAAAAA1242,AAAAAAAAAAAAAAAA1729,AAAA35194} - 30 | {26,81,47,91,34} | {AAAAAAAAAAAAAAAAAAA70104,AAAAAAA80240} - 31 | {80,24,18,21,54} | {AAAAAAAAAAAAAAA13198,AAAAAAAAAAAAAAAAAAA70415,A27153,AAAAAAAAA53663,AAAAAAAAAAAAAAAAA50407,A68938} - 32 | {58,79,82,80,67,75,98,10,41} | {AAAAAAAAAAAAAAAAAA61286,AAA54451,AAAAAAAAAAAAAAAAAAA87527,A96617,51533} - 33 | {74,73} | {A85417,AAAAAAA56483,AAAAA17383,AAAAAAAAAAAAA62159,AAAAAAAAAAAA52814,AAAAAAAAAAAAA85723,AAAAAAAAAAAAAAAAAA55796} - 34 | {70,45} | {AAAAAAAAAAAAAAAAAA71621,AAAAAAAAAAAAAA28620,AAAAAAAAAA55219,AAAAAAAA23648,AAAAAAAAAA22292,AAAAAAA1242} - 35 | {23,40} | {AAAAAAAAAAAA52814,AAAA48949,AAAAAAAAA34727,AAAA8857,AAAAAAAAAAAAAAAAAAA62179,AAAAAAAAAAAAAAA68526,AAAAAAA99836,AAAAAAAA50094,AAAA91194,AAAAAAAAAAAAA73084} - 36 | {79,82,14,52,30,5,79} | {AAAAAAAAA53663,AAAAAAAAAAAAAAAA55798,AAAAAAAAAAAAAAAAAAA89194,AA88409,AAAAAAAAAAAAAAA81326,AAAAAAAAAAAAAAAAA63050,AAAAAAAAAAAAAAAA33598} - 37 | {53,11,81,39,3,78,58,64,74} | {AAAAAAAAAAAAAAAAAAA17075,AAAAAAA66161,AAAAAAAA23648,AAAAAAAAAAAAAA10611} - 38 | {59,5,4,95,28} | {AAAAAAAAAAA82945,A96617,47735,AAAAA12179,AAAAA64669,AAAAAA99807,AA74433,AAAAAAAAAAAAAAAAA59387} - 39 | {82,43,99,16,74} | {AAAAAAAAAAAAAAA67062,AAAAAAA57334,AAAAAAAAAAAAAA65909,A27153,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAAAA43052,AAAAAAAAAA64777,AAAAAAAAAAAA81511,AAAAAAAAAAAAAA65909,AAAAAAAAAAAAAA28620} - 40 | {34} | {AAAAAAAAAAAAAA10611,AAAAAAAAAAAAAAAAAAA1205,AAAAAAAAAAA50956,AAAAAAAAAAAAAAAA31334,AAAAA70466,AAAAAAAA81587,AAAAAAA74623} - 41 | {19,26,63,12,93,73,27,94} | {AAAAAAA79710,AAAAAAAAAA55219,AAAA41702,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAAAAA71621,AAAAAAAAAAAAAAAAA63050,AAAAAAA99836,AAAAAAAAAAAAAA8666} - 42 | {15,76,82,75,8,91} | {AAAAAAAAAAA176,AAAAAA38063,45449,AAAAAA54032,AAAAAAA81898,AA6416,AAAAAAAAAAAAAAAAAAA62179,45449,AAAAA60038,AAAAAAAA81587} - 43 | {39,87,91,97,79,28} | {AAAAAAAAAAA74076,A96617,AAAAAAAAAAAAAAAAAAA89194,AAAAAAAAAAAAAAAAAA55796,AAAAAAAAAAAAAAAA23657,AAAAAAAAAAAA67946} - 44 | {40,58,68,29,54} | {AAAAAAA81898,AAAAAA66777,AAAAAA98232} - 45 | {99,45} | {AAAAAAAA72908,AAAAAAAAAAAAAAAAAAA17075,AA88409,AAAAAAAAAAAAAAAAAA36842,AAAAAAA48038,AAAAAAAAAAAAAA10611} - 46 | {53,24} | {AAAAAAAAAAA53908,AAAAAA54032,AAAAA17383,AAAA48949,AAAAAAAAAA18601,AAAAA64669,45449,AAAAAAAAAAA98051,AAAAAAAAAAAAAAAAAA71621} - 47 | {98,23,64,12,75,61} | {AAA59323,AAAAA95309,AAAAAAAAAAAAAAAA31334,AAAAAAAAA27249,AAAAA17383,AAAAAAAAAAAA37562,AAAAAA1059,A84822,55847,AAAAA70466} - 48 | {76,14} | {AAAAAAAAAAAAA59671,AAAAAAAAAAAAAAAAAAA91804,AAAAAA66777,AAAAAAAAAAAAAAAAAAA89194,AAAAAAAAAAAAAAA36627,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAA73084,AAAAAAA79710,AAAAAAAAAAAAAAA40402,AAAAAAAAAAAAAAAAAAA65037} - 49 | {56,5,54,37,49} | {AA21643,AAAAAAAAAAA92631,AAAAAAAA81587} - 50 | {20,12,37,64,93} | {AAAAAAAAAA5483,AAAAAAAAAAAAAAAAAAA1205,AA6416,AAAAAAAAAAAAAAAAA63050,AAAAAAAAAAAAAAAAAA47955} - 51 | {47} | {AAAAAAAAAAAAAA96505,AAAAAAAAAAAAAAAAAA36842,AAAAA95309,AAAAAAAA81587,AA6416,AAAA91194,AAAAAA58494,AAAAAA1059,AAAAAAAA69452} - 52 | {89,0} | {AAAAAAAAAAAAAAAAAA47955,AAAAAAA48038,AAAAAAAAAAAAAAAAA43052,AAAAAAAAAAAAA73084,AAAAA70466,AAAAAAAAAAAAAAAAA764,AAAAAAAAAAA46154,AA66862} - 53 | {38,17} | {AAAAAAAAAAA21658} - 54 | {70,47} | {AAAAAAAAAAAAAAAAAA54141,AAAAA40681,AAAAAAA48038,AAAAAAAAAAAAAAAA29150,AAAAA41597,AAAAAAAAAAAAAAAAAA59334,AA15322} - 55 | {47,79,47,64,72,25,71,24,93} | {AAAAAAAAAAAAAAAAAA55796,AAAAA62737} - 56 | {33,7,60,54,93,90,77,85,39} | {AAAAAAAAAAAAAAAAAA32918,AA42406} - 57 | {23,45,10,42,36,21,9,96} | {AAAAAAAAAAAAAAAAAAA70415} - 58 | {92} | {AAAAAAAAAAAAAAAA98414,AAAAAAAA23648,AAAAAAAAAAAAAAAAAA55796,AA25381,AAAAAAAAAAA6119} - 59 | {9,69,46,77} | {39557,AAAAAAA89932,AAAAAAAAAAAAAAAAA43052,AAAAAAAAAAAAAAAAA26540,AAA20874,AA6416,AAAAAAAAAAAAAAAAAA47955} - 60 | {62,2,59,38,89} | {AAAAAAA89932,AAAAAAAAAAAAAAAAAAA15356,AA99927,AA17009,AAAAAAAAAAAAAAA35875} - 61 | {72,2,44,95,54,54,13} | {AAAAAAAAAAAAAAAAAAA91804} - 62 | {83,72,29,73} | {AAAAAAAAAAAAA15097,AAAA8857,AAAAAAAAAAAA35809,AAAAAAAAAAAA52814,AAAAAAAAAAAAAAAAAAA38885,AAAAAAAAAAAAAAAAAA24183,AAAAAA43678,A96617} - 63 | {11,4,61,87} | {AAAAAAAAA27249,AAAAAAAAAAAAAAAAAA32918,AAAAAAAAAAAAAAA13198,AAA20874,39557,51533,AAAAAAAAAAA53908,AAAAAAAAAAAAAA96505,AAAAAAAA78938} - 64 | {26,19,34,24,81,78} | {A96617,AAAAAAAAAAAAAAAAAAA70104,A68938,AAAAAAAAAAA53908,AAAAAAAAAAAAAAA453,AA17009,AAAAAAA80240} - 65 | {61,5,76,59,17} | {AAAAAA99807,AAAAA64741,AAAAAAAAAAA53908,AA21643,AAAAAAAAA10012} - 66 | {31,23,70,52,4,33,48,25} | {AAAAAAAAAAAAAAAAA69675,AAAAAAAA50094,AAAAAAAAAAA92631,AAAA35194,39557,AAAAAAA99836} - 67 | {31,94,7,10} | {AAAAAA38063,A96617,AAAA35194,AAAAAAAAAAAA67946} - 68 | {90,43,38} | {AA75092,AAAAAAAAAAAAAAAAA69675,AAAAAAAAAAA92631,AAAAAAAAA10012,AAAAAAAAAAAAA7929,AA21643} - 69 | {67,35,99,85,72,86,44} | {AAAAAAAAAAAAAAAAAAA1205,AAAAAAAA50094,AAAAAAAAAAAAAAAA1729,AAAAAAAAAAAAAAAAAA47955} - 70 | {56,70,83} | {AAAA41702,AAAAAAAAAAA82945,AA21643,AAAAAAAAAAA99000,A27153,AA25381,AAAAAAAAAAAAAA96505,AAAAAAA1242} - 71 | {74,26} | {AAAAAAAAAAA50956,AA74433,AAAAAAA21462,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAA36627,AAAAAAAAAAAAA70254,AAAAAAAAAA43419,39557} - 72 | {22,1,16,78,20,91,83} | {47735,AAAAAAA56483,AAAAAAAAAAAAA93788,AA42406,AAAAAAAAAAAAA73084,AAAAAAAA72908,AAAAAAAAAAAAAAAAAA61286,AAAAA66674,AAAAAAAAAAAAAAAAA50407} - 73 | {88,25,96,78,65,15,29,19} | {AAA54451,AAAAAAAAA27249,AAAAAAA9228,AAAAAAAAAAAAAAA67062,AAAAAAAAAAAAAAAAAAA70415,AAAAA17383,AAAAAAAAAAAAAAAA33598} - 74 | {32} | {AAAAAAAAAAAAAAAA1729,AAAAAAAAAAAAA22860,AAAAAA99807,AAAAA17383,AAAAAAAAAAAAAAA67062,AAAAAAAAAAA15165,AAAAAAAAAAA50956} - 75 | {12,96,83,24,71,89,55} | {AAAA48949,AAAAAAAA29716,AAAAAAAAAAAAAAAAAAA1205,AAAAAAAAAAAA67946,AAAAAAAAAAAAAAAA29150,AAA28075,AAAAAAAAAAAAAAAAA43052} - 76 | {92,55,10,7} | {AAAAAAAAAAAAAAA67062} - 77 | {97,15,32,17,55,59,18,37,50,39} | {AAAAAAAAAAAA67946,AAAAAA54032,AAAAAAAA81587,55847,AAAAAAAAAAAAAA28620,AAAAAAAAAAAAAAAAA43052,AAAAAA75463,AAAA49534,AAAAAAAA44066} - 78 | {55,89,44,84,34} | {AAAAAAAAAAA6119,AAAAAAAAAAAAAA8666,AA99927,AA42406,AAAAAAA81898,AAAAAAA9228,AAAAAAAAAAA92631,AA21643,AAAAAAAAAAAAAA28620} - 79 | {45} | {AAAAAAAAAA646,AAAAAAAAAAAAAAAAAAA70415,AAAAAA43678,AAAAAAAA72908} - 80 | {74,89,44,80,0} | {AAAA35194,AAAAAAAA79710,AAA20874,AAAAAAAAAAAAAAAAAAA70104,AAAAAAAAAAAAA73084,AAAAAAA57334,AAAAAAA9228,AAAAAAAAAAAAA62007} - 81 | {63,77,54,48,61,53,97} | {AAAAAAAAAAAAAAA81326,AAAAAAAAAA22292,AA25381,AAAAAAAAAAA74076,AAAAAAA81898,AAAAAAAAA72121} - 82 | {34,60,4,79,78,16,86,89,42,50} | {AAAAA40681,AAAAAAAAAAAAAAAAAA12591,AAAAAAA80240,AAAAAAAAAAAAAAAA55798,AAAAAAAAAAAAAAAAAAA70104} - 83 | {14,10} | {AAAAAAAAAA22292,AAAAAAAAAAAAA70254,AAAAAAAAAAA6119} - 84 | {11,83,35,13,96,94} | {AAAAA95309,AAAAAAAAAAAAAAAAAA32918,AAAAAAAAAAAAAAAAAA24183} - 85 | {39,60} | {AAAAAAAAAAAAAAAA55798,AAAAAAAAAA22292,AAAAAAA66161,AAAAAAA21462,AAAAAAAAAAAAAAAAAA12591,55847,AAAAAA98232,AAAAAAAAAAA46154} - 86 | {33,81,72,74,45,36,82} | {AAAAAAAA81587,AAAAAAAAAAAAAA96505,45449,AAAA80176} - 87 | {57,27,50,12,97,68} | {AAAAAAAAAAAAAAAAA26540,AAAAAAAAA10012,AAAAAAAAAAAA35809,AAAAAAAAAAAAAAAA29150,AAAAAAAAAAA82945,AAAAAA66777,31228,AAAAAAAAAAAAAAAA23657,AAAAAAAAAAAAAA28620,AAAAAAAAAAAAAA96505} - 88 | {41,90,77,24,6,24} | {AAAA35194,AAAA35194,AAAAAAA80240,AAAAAAAAAAA46154,AAAAAA58494,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAAAAA59334,AAAAAAAAAAAAAAAAAAA91804,AA74433} - 89 | {40,32,17,6,30,88} | {AA44673,AAAAAAAAAAA6119,AAAAAAAAAAAAAAAA23657,AAAAAAAAAAAAAAAAAA47955,AAAAAAAAAAAAAAAA33598,AAAAAAAAAAA33576,AA44673} - 90 | {88,75} | {AAAAA60038,AAAAAAAA23648,AAAAAAAAAAA99000,AAAA41702,AAAAAAAAAAAAA22860,AAAAAAAAAAAAAAA68526} - 91 | {78} | {AAAAAAAAAAAAA62007,AAA99043} - 92 | {85,63,49,45} | {AAAAAAA89932,AAAAAAAAAAAAA22860,AAAAAAAAAAAAAAAAAAA1205,AAAAAAAAAAAA21089} - 93 | {11} | {AAAAAAAAAAA176,AAAAAAAAAAAAAA8666,AAAAAAAAAAAAAAA453,AAAAAAAAAAAAA85723,A68938,AAAAAAAAAAAAA9821,AAAAAAA48038,AAAAAAAAAAAAAAAAA59387,AA99927,AAAAA17383} - 94 | {98,9,85,62,88,91,60,61,38,86} | {AAAAAAAA81587,AAAAA17383,AAAAAAAA81587} - 95 | {47,77} | {AAAAAAAAAAAAAAAAA764,AAAAAAAAAAA74076,AAAAAAAAAA18107,AAAAA40681,AAAAAAAAAAAAAAA35875,AAAAA60038,AAAAAAA56483} - 96 | {23,97,43} | {AAAAAAAAAA646,A87088} - 97 | {54,2,86,65} | {47735,AAAAAAA99836,AAAAAAAAAAAAAAAAA6897,AAAAAAAAAAAAAAAA29150,AAAAAAA80240,AAAAAAAAAAAAAAAA98414,AAAAAAA56483,AAAAAAAAAAAAAAAA29150,AAAAAAA39692,AA21643} - 98 | {38,34,32,89} | {AAAAAAAAAAAAAAAAAA71621,AAAA8857,AAAAAAAAAAAAAAAAAAA65037,AAAAAAAAAAAAAAAA31334,AAAAAAAAAA48845} - 99 | {37,86} | {AAAAAAAAAAAAAAAAAA32918,AAAAA70514,AAAAAAAAA10012,AAAAAAAAAAAAAAAAA59387,AAAAAAAAAA64777,AAAAAAAAAAAAAAAAAAA15356} - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} - 101 | {} | {} - 102 | {NULL} | {NULL} -(102 rows) - -SELECT * FROM array_index_op_test WHERE t && '{}' ORDER BY seqno; - seqno | i | t --------+---+--- -(0 rows) - -SELECT * FROM array_index_op_test WHERE t <@ '{}' ORDER BY seqno; - seqno | i | t --------+----+---- - 101 | {} | {} -(1 row) - --- And try it with a multicolumn GIN index -DROP INDEX intarrayidx, textarrayidx; -CREATE INDEX botharrayidx ON array_index_op_test USING gin (i, t); -SELECT * FROM array_index_op_test WHERE i @> '{32}' ORDER BY seqno; - seqno | i | t --------+---------------------------------+------------------------------------------------------------------------------------------------------------------------------------ - 6 | {39,35,5,94,17,92,60,32} | {AAAAAAAAAAAAAAA35875,AAAAAAAAAAAAAAAA23657} - 74 | {32} | {AAAAAAAAAAAAAAAA1729,AAAAAAAAAAAAA22860,AAAAAA99807,AAAAA17383,AAAAAAAAAAAAAAA67062,AAAAAAAAAAA15165,AAAAAAAAAAA50956} - 77 | {97,15,32,17,55,59,18,37,50,39} | {AAAAAAAAAAAA67946,AAAAAA54032,AAAAAAAA81587,55847,AAAAAAAAAAAAAA28620,AAAAAAAAAAAAAAAAA43052,AAAAAA75463,AAAA49534,AAAAAAAA44066} - 89 | {40,32,17,6,30,88} | {AA44673,AAAAAAAAAAA6119,AAAAAAAAAAAAAAAA23657,AAAAAAAAAAAAAAAAAA47955,AAAAAAAAAAAAAAAA33598,AAAAAAAAAAA33576,AA44673} - 98 | {38,34,32,89} | {AAAAAAAAAAAAAAAAAA71621,AAAA8857,AAAAAAAAAAAAAAAAAAA65037,AAAAAAAAAAAAAAAA31334,AAAAAAAAAA48845} - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(6 rows) - -SELECT * FROM array_index_op_test WHERE i && '{32}' ORDER BY seqno; - seqno | i | t --------+---------------------------------+------------------------------------------------------------------------------------------------------------------------------------ - 6 | {39,35,5,94,17,92,60,32} | {AAAAAAAAAAAAAAA35875,AAAAAAAAAAAAAAAA23657} - 74 | {32} | {AAAAAAAAAAAAAAAA1729,AAAAAAAAAAAAA22860,AAAAAA99807,AAAAA17383,AAAAAAAAAAAAAAA67062,AAAAAAAAAAA15165,AAAAAAAAAAA50956} - 77 | {97,15,32,17,55,59,18,37,50,39} | {AAAAAAAAAAAA67946,AAAAAA54032,AAAAAAAA81587,55847,AAAAAAAAAAAAAA28620,AAAAAAAAAAAAAAAAA43052,AAAAAA75463,AAAA49534,AAAAAAAA44066} - 89 | {40,32,17,6,30,88} | {AA44673,AAAAAAAAAAA6119,AAAAAAAAAAAAAAAA23657,AAAAAAAAAAAAAAAAAA47955,AAAAAAAAAAAAAAAA33598,AAAAAAAAAAA33576,AA44673} - 98 | {38,34,32,89} | {AAAAAAAAAAAAAAAAAA71621,AAAA8857,AAAAAAAAAAAAAAAAAAA65037,AAAAAAAAAAAAAAAA31334,AAAAAAAAAA48845} - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(6 rows) - -SELECT * FROM array_index_op_test WHERE t @> '{AAAAAAA80240}' ORDER BY seqno; - seqno | i | t --------+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------- - 19 | {52,82,17,74,23,46,69,51,75} | {AAAAAAAAAAAAA73084,AAAAA75968,AAAAAAAAAAAAAAAA14047,AAAAAAA80240,AAAAAAAAAAAAAAAAAAA1205,A68938} - 30 | {26,81,47,91,34} | {AAAAAAAAAAAAAAAAAAA70104,AAAAAAA80240} - 64 | {26,19,34,24,81,78} | {A96617,AAAAAAAAAAAAAAAAAAA70104,A68938,AAAAAAAAAAA53908,AAAAAAAAAAAAAAA453,AA17009,AAAAAAA80240} - 82 | {34,60,4,79,78,16,86,89,42,50} | {AAAAA40681,AAAAAAAAAAAAAAAAAA12591,AAAAAAA80240,AAAAAAAAAAAAAAAA55798,AAAAAAAAAAAAAAAAAAA70104} - 88 | {41,90,77,24,6,24} | {AAAA35194,AAAA35194,AAAAAAA80240,AAAAAAAAAAA46154,AAAAAA58494,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAAAAA59334,AAAAAAAAAAAAAAAAAAA91804,AA74433} - 97 | {54,2,86,65} | {47735,AAAAAAA99836,AAAAAAAAAAAAAAAAA6897,AAAAAAAAAAAAAAAA29150,AAAAAAA80240,AAAAAAAAAAAAAAAA98414,AAAAAAA56483,AAAAAAAAAAAAAAAA29150,AAAAAAA39692,AA21643} - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(7 rows) - -SELECT * FROM array_index_op_test WHERE t && '{AAAAAAA80240}' ORDER BY seqno; - seqno | i | t --------+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------- - 19 | {52,82,17,74,23,46,69,51,75} | {AAAAAAAAAAAAA73084,AAAAA75968,AAAAAAAAAAAAAAAA14047,AAAAAAA80240,AAAAAAAAAAAAAAAAAAA1205,A68938} - 30 | {26,81,47,91,34} | {AAAAAAAAAAAAAAAAAAA70104,AAAAAAA80240} - 64 | {26,19,34,24,81,78} | {A96617,AAAAAAAAAAAAAAAAAAA70104,A68938,AAAAAAAAAAA53908,AAAAAAAAAAAAAAA453,AA17009,AAAAAAA80240} - 82 | {34,60,4,79,78,16,86,89,42,50} | {AAAAA40681,AAAAAAAAAAAAAAAAAA12591,AAAAAAA80240,AAAAAAAAAAAAAAAA55798,AAAAAAAAAAAAAAAAAAA70104} - 88 | {41,90,77,24,6,24} | {AAAA35194,AAAA35194,AAAAAAA80240,AAAAAAAAAAA46154,AAAAAA58494,AAAAAAAAAAAAAAAAAAA17075,AAAAAAAAAAAAAAAAAA59334,AAAAAAAAAAAAAAAAAAA91804,AA74433} - 97 | {54,2,86,65} | {47735,AAAAAAA99836,AAAAAAAAAAAAAAAAA6897,AAAAAAAAAAAAAAAA29150,AAAAAAA80240,AAAAAAAAAAAAAAAA98414,AAAAAAA56483,AAAAAAAAAAAAAAAA29150,AAAAAAA39692,AA21643} - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(7 rows) - -SELECT * FROM array_index_op_test WHERE i @> '{32}' AND t && '{AAAAAAA80240}' ORDER BY seqno; - seqno | i | t --------+-----------------------------+------------------------------------------------------------------------------ - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(1 row) - -SELECT * FROM array_index_op_test WHERE i && '{32}' AND t @> '{AAAAAAA80240}' ORDER BY seqno; - seqno | i | t --------+-----------------------------+------------------------------------------------------------------------------ - 100 | {85,32,57,39,49,84,32,3,30} | {AAAAAAA80240,AAAAAAAAAAAAAAAA1729,AAAAA60038,AAAAAAAAAAA92631,AAAAAAAA9523} -(1 row) - -SELECT * FROM array_index_op_test WHERE t = '{}' ORDER BY seqno; - seqno | i | t --------+----+---- - 101 | {} | {} -(1 row) - -SELECT * FROM array_op_test WHERE i = '{NULL}' ORDER BY seqno; - seqno | i | t --------+--------+-------- - 102 | {NULL} | {NULL} -(1 row) - -SELECT * FROM array_op_test WHERE i <@ '{NULL}' ORDER BY seqno; - seqno | i | t --------+----+---- - 101 | {} | {} -(1 row) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; --- --- Try a GIN index with a lot of items with same key. (GIN creates a posting --- tree when there are enough duplicates) --- -CREATE TABLE array_gin_test (a int[]); -INSERT INTO array_gin_test SELECT ARRAY[1, g%5, g] FROM generate_series(1, 10000) g; -CREATE INDEX array_gin_test_idx ON array_gin_test USING gin (a); -SELECT COUNT(*) FROM array_gin_test WHERE a @> '{2}'; - count -------- - 2000 -(1 row) - -DROP TABLE array_gin_test; --- --- Test GIN index's reloptions --- -CREATE INDEX gin_relopts_test ON array_index_op_test USING gin (i) - WITH (FASTUPDATE=on, GIN_PENDING_LIST_LIMIT=128); -\d+ gin_relopts_test - Index "public.gin_relopts_test" - Column | Type | Key? | Definition | Storage | Stats target ---------+---------+------+------------+---------+-------------- - i | integer | yes | i | plain | -gin, for table "public.array_index_op_test" -Options: fastupdate=on, gin_pending_list_limit=128 - --- --- HASH --- -CREATE INDEX hash_i4_index ON hash_i4_heap USING hash (random int4_ops); -CREATE INDEX hash_name_index ON hash_name_heap USING hash (random name_ops); -CREATE INDEX hash_txt_index ON hash_txt_heap USING hash (random text_ops); -CREATE INDEX hash_f8_index ON hash_f8_heap USING hash (random float8_ops) WITH (fillfactor=60); -CREATE UNLOGGED TABLE unlogged_hash_table (id int4); -CREATE INDEX unlogged_hash_index ON unlogged_hash_table USING hash (id int4_ops); -DROP TABLE unlogged_hash_table; --- CREATE INDEX hash_ovfl_index ON hash_ovfl_heap USING hash (x int4_ops); --- Test hash index build tuplesorting. Force hash tuplesort using low --- maintenance_work_mem setting and fillfactor: -SET maintenance_work_mem = '1MB'; -CREATE INDEX hash_tuplesort_idx ON tenk1 USING hash (stringu1 name_ops) WITH (fillfactor = 10); -EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on tenk1 - Recheck Cond: (stringu1 = 'TVAAAA'::name) - -> Bitmap Index Scan on hash_tuplesort_idx - Index Cond: (stringu1 = 'TVAAAA'::name) -(5 rows) - -SELECT count(*) FROM tenk1 WHERE stringu1 = 'TVAAAA'; - count -------- - 14 -(1 row) - -DROP INDEX hash_tuplesort_idx; -RESET maintenance_work_mem; --- --- Test functional index --- -CREATE TABLE func_index_heap (f1 text, f2 text); -CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2)); -INSERT INTO func_index_heap VALUES('ABC','DEF'); -INSERT INTO func_index_heap VALUES('AB','CDEFG'); -INSERT INTO func_index_heap VALUES('QWE','RTY'); --- this should fail because of unique index: -INSERT INTO func_index_heap VALUES('ABCD', 'EF'); -ERROR: duplicate key value violates unique constraint "func_index_index" -DETAIL: Key (textcat(f1, f2))=(ABCDEF) already exists. --- but this shouldn't: -INSERT INTO func_index_heap VALUES('QWERTY'); --- while we're here, see that the metadata looks sane -\d func_index_heap - Table "public.func_index_heap" - Column | Type | Collation | Nullable | Default ---------+------+-----------+----------+--------- - f1 | text | | | - f2 | text | | | -Indexes: - "func_index_index" UNIQUE, btree (textcat(f1, f2)) - -\d func_index_index - Index "public.func_index_index" - Column | Type | Key? | Definition ----------+------+------+----------------- - textcat | text | yes | textcat(f1, f2) -unique, btree, for table "public.func_index_heap" - --- --- Same test, expressional index --- -DROP TABLE func_index_heap; -CREATE TABLE func_index_heap (f1 text, f2 text); -CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops); -INSERT INTO func_index_heap VALUES('ABC','DEF'); -INSERT INTO func_index_heap VALUES('AB','CDEFG'); -INSERT INTO func_index_heap VALUES('QWE','RTY'); --- this should fail because of unique index: -INSERT INTO func_index_heap VALUES('ABCD', 'EF'); -ERROR: duplicate key value violates unique constraint "func_index_index" -DETAIL: Key ((f1 || f2))=(ABCDEF) already exists. --- but this shouldn't: -INSERT INTO func_index_heap VALUES('QWERTY'); --- while we're here, see that the metadata looks sane -\d func_index_heap - Table "public.func_index_heap" - Column | Type | Collation | Nullable | Default ---------+------+-----------+----------+--------- - f1 | text | | | - f2 | text | | | -Indexes: - "func_index_index" UNIQUE, btree ((f1 || f2)) - -\d func_index_index - Index "public.func_index_index" - Column | Type | Key? | Definition ---------+------+------+------------ - expr | text | yes | (f1 || f2) -unique, btree, for table "public.func_index_heap" - --- this should fail because of unsafe column type (anonymous record) -create index on func_index_heap ((f1 || f2), (row(f1, f2))); -ERROR: column "row" has pseudo-type record --- --- Test unique index with included columns --- -CREATE TABLE covering_index_heap (f1 int, f2 int, f3 text); -CREATE UNIQUE INDEX covering_index_index on covering_index_heap (f1,f2) INCLUDE(f3); -INSERT INTO covering_index_heap VALUES(1,1,'AAA'); -INSERT INTO covering_index_heap VALUES(1,2,'AAA'); --- this should fail because of unique index on f1,f2: -INSERT INTO covering_index_heap VALUES(1,2,'BBB'); -ERROR: duplicate key value violates unique constraint "covering_index_index" -DETAIL: Key (f1, f2)=(1, 2) already exists. --- and this shouldn't: -INSERT INTO covering_index_heap VALUES(1,4,'AAA'); --- Try to build index on table that already contains data -CREATE UNIQUE INDEX covering_pkey on covering_index_heap (f1,f2) INCLUDE(f3); --- Try to use existing covering index as primary key -ALTER TABLE covering_index_heap ADD CONSTRAINT covering_pkey PRIMARY KEY USING INDEX -covering_pkey; -DROP TABLE covering_index_heap; --- --- Also try building functional, expressional, and partial indexes on --- tables that already contain data. --- -create unique index hash_f8_index_1 on hash_f8_heap(abs(random)); -create unique index hash_f8_index_2 on hash_f8_heap((seqno + 1), random); -create unique index hash_f8_index_3 on hash_f8_heap(random) where seqno > 1000; --- --- Try some concurrent index builds --- --- Unfortunately this only tests about half the code paths because there are --- no concurrent updates happening to the table at the same time. -CREATE TABLE concur_heap (f1 text, f2 text); --- empty table -CREATE INDEX CONCURRENTLY concur_index1 ON concur_heap(f2,f1); -CREATE INDEX CONCURRENTLY IF NOT EXISTS concur_index1 ON concur_heap(f2,f1); -NOTICE: relation "concur_index1" already exists, skipping -INSERT INTO concur_heap VALUES ('a','b'); -INSERT INTO concur_heap VALUES ('b','b'); --- unique index -CREATE UNIQUE INDEX CONCURRENTLY concur_index2 ON concur_heap(f1); -CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS concur_index2 ON concur_heap(f1); -NOTICE: relation "concur_index2" already exists, skipping --- check if constraint is set up properly to be enforced -INSERT INTO concur_heap VALUES ('b','x'); -ERROR: duplicate key value violates unique constraint "concur_index2" -DETAIL: Key (f1)=(b) already exists. --- check if constraint is enforced properly at build time -CREATE UNIQUE INDEX CONCURRENTLY concur_index3 ON concur_heap(f2); -ERROR: could not create unique index "concur_index3" -DETAIL: Key (f2)=(b) is duplicated. --- test that expression indexes and partial indexes work concurrently -CREATE INDEX CONCURRENTLY concur_index4 on concur_heap(f2) WHERE f1='a'; -CREATE INDEX CONCURRENTLY concur_index5 on concur_heap(f2) WHERE f1='x'; --- here we also check that you can default the index name -CREATE INDEX CONCURRENTLY on concur_heap((f2||f1)); --- You can't do a concurrent index build in a transaction -BEGIN; -CREATE INDEX CONCURRENTLY concur_index7 ON concur_heap(f1); -ERROR: CREATE INDEX CONCURRENTLY cannot run inside a transaction block -COMMIT; --- test where predicate is able to do a transactional update during --- a concurrent build before switching pg_index state flags. -CREATE FUNCTION predicate_stable() RETURNS bool IMMUTABLE -LANGUAGE plpgsql AS $$ -BEGIN - EXECUTE 'SELECT txid_current()'; - RETURN true; -END; $$; -CREATE INDEX CONCURRENTLY concur_index8 ON concur_heap (f1) - WHERE predicate_stable(); -DROP INDEX concur_index8; -DROP FUNCTION predicate_stable(); --- But you can do a regular index build in a transaction -BEGIN; -CREATE INDEX std_index on concur_heap(f2); -COMMIT; --- Failed builds are left invalid by VACUUM FULL, fixed by REINDEX -VACUUM FULL concur_heap; -REINDEX TABLE concur_heap; -ERROR: could not create unique index "concur_index3" -DETAIL: Key (f2)=(b) is duplicated. -DELETE FROM concur_heap WHERE f1 = 'b'; -VACUUM FULL concur_heap; -\d concur_heap - Table "public.concur_heap" - Column | Type | Collation | Nullable | Default ---------+------+-----------+----------+--------- - f1 | text | | | - f2 | text | | | -Indexes: - "concur_heap_expr_idx" btree ((f2 || f1)) - "concur_index1" btree (f2, f1) - "concur_index2" UNIQUE, btree (f1) - "concur_index3" UNIQUE, btree (f2) INVALID - "concur_index4" btree (f2) WHERE f1 = 'a'::text - "concur_index5" btree (f2) WHERE f1 = 'x'::text - "std_index" btree (f2) - -REINDEX TABLE concur_heap; -\d concur_heap - Table "public.concur_heap" - Column | Type | Collation | Nullable | Default ---------+------+-----------+----------+--------- - f1 | text | | | - f2 | text | | | -Indexes: - "concur_heap_expr_idx" btree ((f2 || f1)) - "concur_index1" btree (f2, f1) - "concur_index2" UNIQUE, btree (f1) - "concur_index3" UNIQUE, btree (f2) - "concur_index4" btree (f2) WHERE f1 = 'a'::text - "concur_index5" btree (f2) WHERE f1 = 'x'::text - "std_index" btree (f2) - --- Temporary tables with concurrent builds and on-commit actions --- CONCURRENTLY used with CREATE INDEX and DROP INDEX is ignored. --- PRESERVE ROWS, the default. -CREATE TEMP TABLE concur_temp (f1 int, f2 text) - ON COMMIT PRESERVE ROWS; -INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); -CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); -DROP INDEX CONCURRENTLY concur_temp_ind; -DROP TABLE concur_temp; --- ON COMMIT DROP -BEGIN; -CREATE TEMP TABLE concur_temp (f1 int, f2 text) - ON COMMIT DROP; -INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); --- Fails when running in a transaction. -CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); -ERROR: CREATE INDEX CONCURRENTLY cannot run inside a transaction block -COMMIT; --- ON COMMIT DELETE ROWS -CREATE TEMP TABLE concur_temp (f1 int, f2 text) - ON COMMIT DELETE ROWS; -INSERT INTO concur_temp VALUES (1, 'foo'), (2, 'bar'); -CREATE INDEX CONCURRENTLY concur_temp_ind ON concur_temp(f1); -DROP INDEX CONCURRENTLY concur_temp_ind; -DROP TABLE concur_temp; --- --- Try some concurrent index drops --- -DROP INDEX CONCURRENTLY "concur_index2"; -- works -DROP INDEX CONCURRENTLY IF EXISTS "concur_index2"; -- notice -NOTICE: index "concur_index2" does not exist, skipping --- failures -DROP INDEX CONCURRENTLY "concur_index2", "concur_index3"; -ERROR: DROP INDEX CONCURRENTLY does not support dropping multiple objects -BEGIN; -DROP INDEX CONCURRENTLY "concur_index5"; -ERROR: DROP INDEX CONCURRENTLY cannot run inside a transaction block -ROLLBACK; --- successes -DROP INDEX CONCURRENTLY IF EXISTS "concur_index3"; -DROP INDEX CONCURRENTLY "concur_index4"; -DROP INDEX CONCURRENTLY "concur_index5"; -DROP INDEX CONCURRENTLY "concur_index1"; -DROP INDEX CONCURRENTLY "concur_heap_expr_idx"; -\d concur_heap - Table "public.concur_heap" - Column | Type | Collation | Nullable | Default ---------+------+-----------+----------+--------- - f1 | text | | | - f2 | text | | | -Indexes: - "std_index" btree (f2) - -DROP TABLE concur_heap; --- --- Test ADD CONSTRAINT USING INDEX --- -CREATE TABLE cwi_test( a int , b varchar(10), c char); --- add some data so that all tests have something to work with. -INSERT INTO cwi_test VALUES(1, 2), (3, 4), (5, 6); -CREATE UNIQUE INDEX cwi_uniq_idx ON cwi_test(a , b); -ALTER TABLE cwi_test ADD primary key USING INDEX cwi_uniq_idx; -\d cwi_test - Table "public.cwi_test" - Column | Type | Collation | Nullable | Default ---------+-----------------------+-----------+----------+--------- - a | integer | | not null | - b | character varying(10) | | not null | - c | character(1) | | | -Indexes: - "cwi_uniq_idx" PRIMARY KEY, btree (a, b) - -\d cwi_uniq_idx - Index "public.cwi_uniq_idx" - Column | Type | Key? | Definition ---------+-----------------------+------+------------ - a | integer | yes | a - b | character varying(10) | yes | b -primary key, btree, for table "public.cwi_test" - -CREATE UNIQUE INDEX cwi_uniq2_idx ON cwi_test(b , a); -ALTER TABLE cwi_test DROP CONSTRAINT cwi_uniq_idx, - ADD CONSTRAINT cwi_replaced_pkey PRIMARY KEY - USING INDEX cwi_uniq2_idx; -NOTICE: ALTER TABLE / ADD CONSTRAINT USING INDEX will rename index "cwi_uniq2_idx" to "cwi_replaced_pkey" -\d cwi_test - Table "public.cwi_test" - Column | Type | Collation | Nullable | Default ---------+-----------------------+-----------+----------+--------- - a | integer | | not null | - b | character varying(10) | | not null | - c | character(1) | | | -Indexes: - "cwi_replaced_pkey" PRIMARY KEY, btree (b, a) - -\d cwi_replaced_pkey - Index "public.cwi_replaced_pkey" - Column | Type | Key? | Definition ---------+-----------------------+------+------------ - b | character varying(10) | yes | b - a | integer | yes | a -primary key, btree, for table "public.cwi_test" - -DROP INDEX cwi_replaced_pkey; -- Should fail; a constraint depends on it -ERROR: cannot drop index cwi_replaced_pkey because constraint cwi_replaced_pkey on table cwi_test requires it -HINT: You can drop constraint cwi_replaced_pkey on table cwi_test instead. --- Check that non-default index options are rejected -CREATE UNIQUE INDEX cwi_uniq3_idx ON cwi_test(a desc); -ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx; -- fail -ERROR: index "cwi_uniq3_idx" column number 1 does not have default sorting behavior -LINE 1: ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq3_idx; - ^ -DETAIL: Cannot create a primary key or unique constraint using such an index. -CREATE UNIQUE INDEX cwi_uniq4_idx ON cwi_test(b collate "POSIX"); -ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx; -- fail -ERROR: index "cwi_uniq4_idx" column number 1 does not have default sorting behavior -LINE 1: ALTER TABLE cwi_test ADD UNIQUE USING INDEX cwi_uniq4_idx; - ^ -DETAIL: Cannot create a primary key or unique constraint using such an index. -DROP TABLE cwi_test; --- ADD CONSTRAINT USING INDEX is forbidden on partitioned tables -CREATE TABLE cwi_test(a int) PARTITION BY hash (a); -create unique index on cwi_test (a); -alter table cwi_test add primary key using index cwi_test_a_idx ; -ERROR: ALTER TABLE / ADD CONSTRAINT USING INDEX is not supported on partitioned tables -DROP TABLE cwi_test; --- --- Check handling of indexes on system columns --- -CREATE TABLE syscol_table (a INT); --- System columns cannot be indexed -CREATE INDEX ON syscolcol_table (ctid); -ERROR: relation "syscolcol_table" does not exist --- nor used in expressions -CREATE INDEX ON syscol_table ((ctid >= '(1000,0)')); -ERROR: index creation on system columns is not supported --- nor used in predicates -CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)'; -ERROR: index creation on system columns is not supported -DROP TABLE syscol_table; --- --- Tests for IS NULL/IS NOT NULL with b-tree indexes --- -SELECT unique1, unique2 INTO onek_with_null FROM onek; -INSERT INTO onek_with_null (unique1,unique2) VALUES (NULL, -1), (NULL, NULL); -CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2,unique1); -SET enable_seqscan = OFF; -SET enable_indexscan = ON; -SET enable_bitmapscan = ON; -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; - count -------- - 2 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; - count -------- - 1000 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; - count -------- - 499 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; - count -------- - 0 -(1 row) - -DROP INDEX onek_nulltest; -CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc,unique1); -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; - count -------- - 2 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; - count -------- - 1000 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; - count -------- - 499 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; - count -------- - 0 -(1 row) - -DROP INDEX onek_nulltest; -CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 desc nulls last,unique1); -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; - count -------- - 2 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; - count -------- - 1000 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; - count -------- - 499 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; - count -------- - 0 -(1 row) - -DROP INDEX onek_nulltest; -CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2 nulls first,unique1); -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL; - count -------- - 2 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL; - count -------- - 1000 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique2 IS NOT NULL; - count -------- - 1 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NOT NULL AND unique1 > 500; - count -------- - 499 -(1 row) - -SELECT count(*) FROM onek_with_null WHERE unique1 IS NULL AND unique1 > 500; - count -------- - 0 -(1 row) - -DROP INDEX onek_nulltest; --- Check initial-positioning logic too -CREATE UNIQUE INDEX onek_nulltest ON onek_with_null (unique2); -SET enable_seqscan = OFF; -SET enable_indexscan = ON; -SET enable_bitmapscan = OFF; -SELECT unique1, unique2 FROM onek_with_null - ORDER BY unique2 LIMIT 2; - unique1 | unique2 ----------+--------- - | -1 - 147 | 0 -(2 rows) - -SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 - ORDER BY unique2 LIMIT 2; - unique1 | unique2 ----------+--------- - | -1 - 147 | 0 -(2 rows) - -SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= 0 - ORDER BY unique2 LIMIT 2; - unique1 | unique2 ----------+--------- - 147 | 0 - 931 | 1 -(2 rows) - -SELECT unique1, unique2 FROM onek_with_null - ORDER BY unique2 DESC LIMIT 2; - unique1 | unique2 ----------+--------- - | - 278 | 999 -(2 rows) - -SELECT unique1, unique2 FROM onek_with_null WHERE unique2 >= -1 - ORDER BY unique2 DESC LIMIT 2; - unique1 | unique2 ----------+--------- - 278 | 999 - 0 | 998 -(2 rows) - -SELECT unique1, unique2 FROM onek_with_null WHERE unique2 < 999 - ORDER BY unique2 DESC LIMIT 2; - unique1 | unique2 ----------+--------- - 0 | 998 - 744 | 997 -(2 rows) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; -DROP TABLE onek_with_null; --- --- Check bitmap index path planning --- -EXPLAIN (COSTS OFF) -SELECT * FROM tenk1 - WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on tenk1 - Recheck Cond: (((thousand = 42) AND (tenthous = 1)) OR ((thousand = 42) AND (tenthous = 3)) OR ((thousand = 42) AND (tenthous = 42))) - -> BitmapOr - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: ((thousand = 42) AND (tenthous = 1)) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: ((thousand = 42) AND (tenthous = 3)) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: ((thousand = 42) AND (tenthous = 42)) -(9 rows) - -SELECT * FROM tenk1 - WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); - unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ----------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- - 42 | 5530 | 0 | 2 | 2 | 2 | 42 | 42 | 42 | 42 | 42 | 84 | 85 | QBAAAA | SEIAAA | OOOOxx -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM tenk1 - WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); - QUERY PLAN ---------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on tenk1 - Recheck Cond: ((hundred = 42) AND ((thousand = 42) OR (thousand = 99))) - -> BitmapAnd - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred = 42) - -> BitmapOr - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = 42) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = 99) -(11 rows) - -SELECT count(*) FROM tenk1 - WHERE hundred = 42 AND (thousand = 42 OR thousand = 99); - count -------- - 10 -(1 row) - --- --- Check behavior with duplicate index column contents --- -CREATE TABLE dupindexcols AS - SELECT unique1 as id, stringu2::text as f1 FROM tenk1; -CREATE INDEX dupindexcols_i ON dupindexcols (f1, id, f1 text_pattern_ops); -ANALYZE dupindexcols; -EXPLAIN (COSTS OFF) - SELECT count(*) FROM dupindexcols - WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on dupindexcols - Recheck Cond: ((f1 >= 'WA'::text) AND (f1 <= 'ZZZ'::text) AND (id < 1000) AND (f1 ~<~ 'YX'::text)) - -> Bitmap Index Scan on dupindexcols_i - Index Cond: ((f1 >= 'WA'::text) AND (f1 <= 'ZZZ'::text) AND (id < 1000) AND (f1 ~<~ 'YX'::text)) -(5 rows) - -SELECT count(*) FROM dupindexcols - WHERE f1 BETWEEN 'WA' AND 'ZZZ' and id < 1000 and f1 ~<~ 'YX'; - count -------- - 97 -(1 row) - --- --- Check ordering of =ANY indexqual results (bug in 9.2.0) --- -vacuum tenk1; -- ensure we get consistent plans here -explain (costs off) -SELECT unique1 FROM tenk1 -WHERE unique1 IN (1,42,7) -ORDER BY unique1; - QUERY PLAN -------------------------------------------------------- - Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = ANY ('{1,42,7}'::integer[])) -(2 rows) - -SELECT unique1 FROM tenk1 -WHERE unique1 IN (1,42,7) -ORDER BY unique1; - unique1 ---------- - 1 - 7 - 42 -(3 rows) - -explain (costs off) -SELECT thousand, tenthous FROM tenk1 -WHERE thousand < 2 AND tenthous IN (1001,3000) -ORDER BY thousand; - QUERY PLAN -------------------------------------------------------- - Index Only Scan using tenk1_thous_tenthous on tenk1 - Index Cond: (thousand < 2) - Filter: (tenthous = ANY ('{1001,3000}'::integer[])) -(3 rows) - -SELECT thousand, tenthous FROM tenk1 -WHERE thousand < 2 AND tenthous IN (1001,3000) -ORDER BY thousand; - thousand | tenthous -----------+---------- - 0 | 3000 - 1 | 1001 -(2 rows) - -SET enable_indexonlyscan = OFF; -explain (costs off) -SELECT thousand, tenthous FROM tenk1 -WHERE thousand < 2 AND tenthous IN (1001,3000) -ORDER BY thousand; - QUERY PLAN --------------------------------------------------------------------------------------- - Sort - Sort Key: thousand - -> Index Scan using tenk1_thous_tenthous on tenk1 - Index Cond: ((thousand < 2) AND (tenthous = ANY ('{1001,3000}'::integer[]))) -(4 rows) - -SELECT thousand, tenthous FROM tenk1 -WHERE thousand < 2 AND tenthous IN (1001,3000) -ORDER BY thousand; - thousand | tenthous -----------+---------- - 0 | 3000 - 1 | 1001 -(2 rows) - -RESET enable_indexonlyscan; --- --- Check elimination of constant-NULL subexpressions --- -explain (costs off) - select * from tenk1 where (thousand, tenthous) in ((1,1001), (null,null)); - QUERY PLAN ------------------------------------------------------- - Index Scan using tenk1_thous_tenthous on tenk1 - Index Cond: ((thousand = 1) AND (tenthous = 1001)) -(2 rows) - --- --- Check matching of boolean index columns to WHERE conditions and sort keys --- -create temp table boolindex (b bool, i int, unique(b, i), junk float); -explain (costs off) - select * from boolindex order by b, i limit 10; - QUERY PLAN -------------------------------------------------------- - Limit - -> Index Scan using boolindex_b_i_key on boolindex -(2 rows) - -explain (costs off) - select * from boolindex where b order by i limit 10; - QUERY PLAN -------------------------------------------------------- - Limit - -> Index Scan using boolindex_b_i_key on boolindex - Index Cond: (b = true) -(3 rows) - -explain (costs off) - select * from boolindex where b = true order by i desc limit 10; - QUERY PLAN ----------------------------------------------------------------- - Limit - -> Index Scan Backward using boolindex_b_i_key on boolindex - Index Cond: (b = true) -(3 rows) - -explain (costs off) - select * from boolindex where not b order by i limit 10; - QUERY PLAN -------------------------------------------------------- - Limit - -> Index Scan using boolindex_b_i_key on boolindex - Index Cond: (b = false) -(3 rows) - -explain (costs off) - select * from boolindex where b is true order by i desc limit 10; - QUERY PLAN ----------------------------------------------------------------- - Limit - -> Index Scan Backward using boolindex_b_i_key on boolindex - Index Cond: (b = true) -(3 rows) - -explain (costs off) - select * from boolindex where b is false order by i desc limit 10; - QUERY PLAN ----------------------------------------------------------------- - Limit - -> Index Scan Backward using boolindex_b_i_key on boolindex - Index Cond: (b = false) -(3 rows) - --- --- REINDEX (VERBOSE) --- -CREATE TABLE reindex_verbose(id integer primary key); -\set VERBOSITY terse \\ -- suppress machine-dependent details -REINDEX (VERBOSE) TABLE reindex_verbose; -INFO: index "reindex_verbose_pkey" was reindexed -\set VERBOSITY default -DROP TABLE reindex_verbose; --- --- REINDEX CONCURRENTLY --- -CREATE TABLE concur_reindex_tab (c1 int); --- REINDEX -REINDEX TABLE concur_reindex_tab; -- notice -NOTICE: table "concur_reindex_tab" has no indexes to reindex -REINDEX TABLE CONCURRENTLY concur_reindex_tab; -- notice -NOTICE: table "concur_reindex_tab" has no indexes that can be reindexed concurrently -ALTER TABLE concur_reindex_tab ADD COLUMN c2 text; -- add toast index --- Normal index with integer column -CREATE UNIQUE INDEX concur_reindex_ind1 ON concur_reindex_tab(c1); --- Normal index with text column -CREATE INDEX concur_reindex_ind2 ON concur_reindex_tab(c2); --- UNIQUE index with expression -CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1)); --- Duplicate column names -CREATE INDEX concur_reindex_ind4 ON concur_reindex_tab(c1, c1, c2); --- Create table for check on foreign key dependence switch with indexes swapped -ALTER TABLE concur_reindex_tab ADD PRIMARY KEY USING INDEX concur_reindex_ind1; -CREATE TABLE concur_reindex_tab2 (c1 int REFERENCES concur_reindex_tab); -INSERT INTO concur_reindex_tab VALUES (1, 'a'); -INSERT INTO concur_reindex_tab VALUES (2, 'a'); --- Reindex concurrently of exclusion constraint currently not supported -CREATE TABLE concur_reindex_tab3 (c1 int, c2 int4range, EXCLUDE USING gist (c2 WITH &&)); -INSERT INTO concur_reindex_tab3 VALUES (3, '[1,2]'); -REINDEX INDEX CONCURRENTLY concur_reindex_tab3_c2_excl; -- error -ERROR: concurrent index creation for exclusion constraints is not supported -REINDEX TABLE CONCURRENTLY concur_reindex_tab3; -- succeeds with warning -WARNING: cannot reindex exclusion constraint index "public.concur_reindex_tab3_c2_excl" concurrently, skipping -INSERT INTO concur_reindex_tab3 VALUES (4, '[2,4]'); -ERROR: conflicting key value violates exclusion constraint "concur_reindex_tab3_c2_excl" -DETAIL: Key (c2)=([2,5)) conflicts with existing key (c2)=([1,3)). --- Check materialized views -CREATE MATERIALIZED VIEW concur_reindex_matview AS SELECT * FROM concur_reindex_tab; --- Dependency lookup before and after the follow-up REINDEX commands. --- These should remain consistent. -SELECT pg_describe_object(classid, objid, objsubid) as obj, - pg_describe_object(refclassid,refobjid,refobjsubid) as objref, - deptype -FROM pg_depend -WHERE classid = 'pg_class'::regclass AND - objid in ('concur_reindex_tab'::regclass, - 'concur_reindex_ind1'::regclass, - 'concur_reindex_ind2'::regclass, - 'concur_reindex_ind3'::regclass, - 'concur_reindex_ind4'::regclass, - 'concur_reindex_matview'::regclass) - ORDER BY 1, 2; - obj | objref | deptype -------------------------------------------+------------------------------------------------------------+--------- - index concur_reindex_ind1 | constraint concur_reindex_ind1 on table concur_reindex_tab | i - index concur_reindex_ind2 | column c2 of table concur_reindex_tab | a - index concur_reindex_ind3 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind3 | table concur_reindex_tab | a - index concur_reindex_ind4 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind4 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind4 | column c2 of table concur_reindex_tab | a - materialized view concur_reindex_matview | schema public | n - table concur_reindex_tab | schema public | n -(9 rows) - -REINDEX INDEX CONCURRENTLY concur_reindex_ind1; -REINDEX TABLE CONCURRENTLY concur_reindex_tab; -REINDEX TABLE CONCURRENTLY concur_reindex_matview; -SELECT pg_describe_object(classid, objid, objsubid) as obj, - pg_describe_object(refclassid,refobjid,refobjsubid) as objref, - deptype -FROM pg_depend -WHERE classid = 'pg_class'::regclass AND - objid in ('concur_reindex_tab'::regclass, - 'concur_reindex_ind1'::regclass, - 'concur_reindex_ind2'::regclass, - 'concur_reindex_ind3'::regclass, - 'concur_reindex_ind4'::regclass, - 'concur_reindex_matview'::regclass) - ORDER BY 1, 2; - obj | objref | deptype -------------------------------------------+------------------------------------------------------------+--------- - index concur_reindex_ind1 | constraint concur_reindex_ind1 on table concur_reindex_tab | i - index concur_reindex_ind2 | column c2 of table concur_reindex_tab | a - index concur_reindex_ind3 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind3 | table concur_reindex_tab | a - index concur_reindex_ind4 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind4 | column c1 of table concur_reindex_tab | a - index concur_reindex_ind4 | column c2 of table concur_reindex_tab | a - materialized view concur_reindex_matview | schema public | n - table concur_reindex_tab | schema public | n -(9 rows) - --- Check that comments are preserved -CREATE TABLE testcomment (i int); -CREATE INDEX testcomment_idx1 ON testcomment (i); -COMMENT ON INDEX testcomment_idx1 IS 'test comment'; -SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); - obj_description ------------------ - test comment -(1 row) - -REINDEX TABLE testcomment; -SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); - obj_description ------------------ - test comment -(1 row) - -REINDEX TABLE CONCURRENTLY testcomment ; -SELECT obj_description('testcomment_idx1'::regclass, 'pg_class'); - obj_description ------------------ - test comment -(1 row) - -DROP TABLE testcomment; --- Check that indisclustered updates are preserved -CREATE TABLE concur_clustered(i int); -CREATE INDEX concur_clustered_i_idx ON concur_clustered(i); -ALTER TABLE concur_clustered CLUSTER ON concur_clustered_i_idx; -REINDEX TABLE CONCURRENTLY concur_clustered; -SELECT indexrelid::regclass, indisclustered FROM pg_index - WHERE indrelid = 'concur_clustered'::regclass; - indexrelid | indisclustered -------------------------+---------------- - concur_clustered_i_idx | t -(1 row) - -DROP TABLE concur_clustered; --- Check that indisreplident updates are preserved. -CREATE TABLE concur_replident(i int NOT NULL); -CREATE UNIQUE INDEX concur_replident_i_idx ON concur_replident(i); -ALTER TABLE concur_replident REPLICA IDENTITY - USING INDEX concur_replident_i_idx; -SELECT indexrelid::regclass, indisreplident FROM pg_index - WHERE indrelid = 'concur_replident'::regclass; - indexrelid | indisreplident -------------------------+---------------- - concur_replident_i_idx | t -(1 row) - -REINDEX TABLE CONCURRENTLY concur_replident; -SELECT indexrelid::regclass, indisreplident FROM pg_index - WHERE indrelid = 'concur_replident'::regclass; - indexrelid | indisreplident -------------------------+---------------- - concur_replident_i_idx | t -(1 row) - -DROP TABLE concur_replident; --- Check that opclass parameters are preserved -CREATE TABLE concur_appclass_tab(i tsvector, j tsvector, k tsvector); -CREATE INDEX concur_appclass_ind on concur_appclass_tab - USING gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')); -CREATE INDEX concur_appclass_ind_2 on concur_appclass_tab - USING gist (k tsvector_ops (siglen='300'), j tsvector_ops); -REINDEX TABLE CONCURRENTLY concur_appclass_tab; -\d concur_appclass_tab - Table "public.concur_appclass_tab" - Column | Type | Collation | Nullable | Default ---------+----------+-----------+----------+--------- - i | tsvector | | | - j | tsvector | | | - k | tsvector | | | -Indexes: - "concur_appclass_ind" gist (i tsvector_ops (siglen='1000'), j tsvector_ops (siglen='500')) - "concur_appclass_ind_2" gist (k tsvector_ops (siglen='300'), j) - -DROP TABLE concur_appclass_tab; --- Partitions --- Create some partitioned tables -CREATE TABLE concur_reindex_part (c1 int, c2 int) PARTITION BY RANGE (c1); -CREATE TABLE concur_reindex_part_0 PARTITION OF concur_reindex_part - FOR VALUES FROM (0) TO (10) PARTITION BY list (c2); -CREATE TABLE concur_reindex_part_0_1 PARTITION OF concur_reindex_part_0 - FOR VALUES IN (1); -CREATE TABLE concur_reindex_part_0_2 PARTITION OF concur_reindex_part_0 - FOR VALUES IN (2); --- This partitioned table will have no partitions. -CREATE TABLE concur_reindex_part_10 PARTITION OF concur_reindex_part - FOR VALUES FROM (10) TO (20) PARTITION BY list (c2); --- Create some partitioned indexes -CREATE INDEX concur_reindex_part_index ON ONLY concur_reindex_part (c1); -CREATE INDEX concur_reindex_part_index_0 ON ONLY concur_reindex_part_0 (c1); -ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_0; --- This partitioned index will have no partitions. -CREATE INDEX concur_reindex_part_index_10 ON ONLY concur_reindex_part_10 (c1); -ALTER INDEX concur_reindex_part_index ATTACH PARTITION concur_reindex_part_index_10; -CREATE INDEX concur_reindex_part_index_0_1 ON ONLY concur_reindex_part_0_1 (c1); -ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_1; -CREATE INDEX concur_reindex_part_index_0_2 ON ONLY concur_reindex_part_0_2 (c1); -ALTER INDEX concur_reindex_part_index_0 ATTACH PARTITION concur_reindex_part_index_0_2; -SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') - ORDER BY relid, level; - relid | parentrelid | level --------------------------------+-----------------------------+------- - concur_reindex_part_index | | 0 - concur_reindex_part_index_0 | concur_reindex_part_index | 1 - concur_reindex_part_index_10 | concur_reindex_part_index | 1 - concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 - concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 -(5 rows) - --- REINDEX fails for partitioned indexes -REINDEX INDEX concur_reindex_part_index_10; -ERROR: REINDEX is not yet implemented for partitioned indexes -REINDEX INDEX CONCURRENTLY concur_reindex_part_index_10; -ERROR: REINDEX is not yet implemented for partitioned indexes --- REINDEX is a no-op for partitioned tables -REINDEX TABLE concur_reindex_part_10; -WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10" -NOTICE: table "concur_reindex_part_10" has no indexes to reindex -REINDEX TABLE CONCURRENTLY concur_reindex_part_10; -WARNING: REINDEX of partitioned tables is not yet implemented, skipping "concur_reindex_part_10" -NOTICE: table "concur_reindex_part_10" has no indexes that can be reindexed concurrently -SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') - ORDER BY relid, level; - relid | parentrelid | level --------------------------------+-----------------------------+------- - concur_reindex_part_index | | 0 - concur_reindex_part_index_0 | concur_reindex_part_index | 1 - concur_reindex_part_index_10 | concur_reindex_part_index | 1 - concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 - concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 -(5 rows) - --- REINDEX should preserve dependencies of partition tree. -SELECT pg_describe_object(classid, objid, objsubid) as obj, - pg_describe_object(refclassid,refobjid,refobjsubid) as objref, - deptype -FROM pg_depend -WHERE classid = 'pg_class'::regclass AND - objid in ('concur_reindex_part'::regclass, - 'concur_reindex_part_0'::regclass, - 'concur_reindex_part_0_1'::regclass, - 'concur_reindex_part_0_2'::regclass, - 'concur_reindex_part_index'::regclass, - 'concur_reindex_part_index_0'::regclass, - 'concur_reindex_part_index_0_1'::regclass, - 'concur_reindex_part_index_0_2'::regclass) - ORDER BY 1, 2; - obj | objref | deptype -------------------------------------------+--------------------------------------------+--------- - column c1 of table concur_reindex_part | table concur_reindex_part | i - column c2 of table concur_reindex_part_0 | table concur_reindex_part_0 | i - index concur_reindex_part_index | column c1 of table concur_reindex_part | a - index concur_reindex_part_index_0 | column c1 of table concur_reindex_part_0 | a - index concur_reindex_part_index_0 | index concur_reindex_part_index | P - index concur_reindex_part_index_0 | table concur_reindex_part_0 | S - index concur_reindex_part_index_0_1 | column c1 of table concur_reindex_part_0_1 | a - index concur_reindex_part_index_0_1 | index concur_reindex_part_index_0 | P - index concur_reindex_part_index_0_1 | table concur_reindex_part_0_1 | S - index concur_reindex_part_index_0_2 | column c1 of table concur_reindex_part_0_2 | a - index concur_reindex_part_index_0_2 | index concur_reindex_part_index_0 | P - index concur_reindex_part_index_0_2 | table concur_reindex_part_0_2 | S - table concur_reindex_part | schema public | n - table concur_reindex_part_0 | schema public | n - table concur_reindex_part_0 | table concur_reindex_part | a - table concur_reindex_part_0_1 | schema public | n - table concur_reindex_part_0_1 | table concur_reindex_part_0 | a - table concur_reindex_part_0_2 | schema public | n - table concur_reindex_part_0_2 | table concur_reindex_part_0 | a -(19 rows) - -REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_1; -REINDEX INDEX CONCURRENTLY concur_reindex_part_index_0_2; -SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') - ORDER BY relid, level; - relid | parentrelid | level --------------------------------+-----------------------------+------- - concur_reindex_part_index | | 0 - concur_reindex_part_index_0 | concur_reindex_part_index | 1 - concur_reindex_part_index_10 | concur_reindex_part_index | 1 - concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 - concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 -(5 rows) - -REINDEX TABLE CONCURRENTLY concur_reindex_part_0_1; -REINDEX TABLE CONCURRENTLY concur_reindex_part_0_2; -SELECT pg_describe_object(classid, objid, objsubid) as obj, - pg_describe_object(refclassid,refobjid,refobjsubid) as objref, - deptype -FROM pg_depend -WHERE classid = 'pg_class'::regclass AND - objid in ('concur_reindex_part'::regclass, - 'concur_reindex_part_0'::regclass, - 'concur_reindex_part_0_1'::regclass, - 'concur_reindex_part_0_2'::regclass, - 'concur_reindex_part_index'::regclass, - 'concur_reindex_part_index_0'::regclass, - 'concur_reindex_part_index_0_1'::regclass, - 'concur_reindex_part_index_0_2'::regclass) - ORDER BY 1, 2; - obj | objref | deptype -------------------------------------------+--------------------------------------------+--------- - column c1 of table concur_reindex_part | table concur_reindex_part | i - column c2 of table concur_reindex_part_0 | table concur_reindex_part_0 | i - index concur_reindex_part_index | column c1 of table concur_reindex_part | a - index concur_reindex_part_index_0 | column c1 of table concur_reindex_part_0 | a - index concur_reindex_part_index_0 | index concur_reindex_part_index | P - index concur_reindex_part_index_0 | table concur_reindex_part_0 | S - index concur_reindex_part_index_0_1 | column c1 of table concur_reindex_part_0_1 | a - index concur_reindex_part_index_0_1 | index concur_reindex_part_index_0 | P - index concur_reindex_part_index_0_1 | table concur_reindex_part_0_1 | S - index concur_reindex_part_index_0_2 | column c1 of table concur_reindex_part_0_2 | a - index concur_reindex_part_index_0_2 | index concur_reindex_part_index_0 | P - index concur_reindex_part_index_0_2 | table concur_reindex_part_0_2 | S - table concur_reindex_part | schema public | n - table concur_reindex_part_0 | schema public | n - table concur_reindex_part_0 | table concur_reindex_part | a - table concur_reindex_part_0_1 | schema public | n - table concur_reindex_part_0_1 | table concur_reindex_part_0 | a - table concur_reindex_part_0_2 | schema public | n - table concur_reindex_part_0_2 | table concur_reindex_part_0 | a -(19 rows) - -SELECT relid, parentrelid, level FROM pg_partition_tree('concur_reindex_part_index') - ORDER BY relid, level; - relid | parentrelid | level --------------------------------+-----------------------------+------- - concur_reindex_part_index | | 0 - concur_reindex_part_index_0 | concur_reindex_part_index | 1 - concur_reindex_part_index_10 | concur_reindex_part_index | 1 - concur_reindex_part_index_0_1 | concur_reindex_part_index_0 | 2 - concur_reindex_part_index_0_2 | concur_reindex_part_index_0 | 2 -(5 rows) - -DROP TABLE concur_reindex_part; --- Check errors --- Cannot run inside a transaction block -BEGIN; -REINDEX TABLE CONCURRENTLY concur_reindex_tab; -ERROR: REINDEX CONCURRENTLY cannot run inside a transaction block -COMMIT; -REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation -ERROR: cannot reindex system catalogs concurrently -REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index -ERROR: cannot reindex system catalogs concurrently --- These are the toast table and index of pg_authid. -REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table -ERROR: cannot reindex system catalogs concurrently -REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index -ERROR: cannot reindex system catalogs concurrently -REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM -ERROR: cannot reindex system catalogs concurrently --- Warns about catalog relations -REINDEX SCHEMA CONCURRENTLY pg_catalog; -WARNING: cannot reindex system catalogs concurrently, skipping all --- Check the relation status, there should not be invalid indexes -\d concur_reindex_tab - Table "public.concur_reindex_tab" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - c1 | integer | | not null | - c2 | text | | | -Indexes: - "concur_reindex_ind1" PRIMARY KEY, btree (c1) - "concur_reindex_ind2" btree (c2) - "concur_reindex_ind3" UNIQUE, btree (abs(c1)) - "concur_reindex_ind4" btree (c1, c1, c2) -Referenced by: - TABLE "concur_reindex_tab2" CONSTRAINT "concur_reindex_tab2_c1_fkey" FOREIGN KEY (c1) REFERENCES concur_reindex_tab(c1) - -DROP MATERIALIZED VIEW concur_reindex_matview; -DROP TABLE concur_reindex_tab, concur_reindex_tab2, concur_reindex_tab3; --- Check handling of invalid indexes -CREATE TABLE concur_reindex_tab4 (c1 int); -INSERT INTO concur_reindex_tab4 VALUES (1), (1), (2); --- This trick creates an invalid index. -CREATE UNIQUE INDEX CONCURRENTLY concur_reindex_ind5 ON concur_reindex_tab4 (c1); -ERROR: could not create unique index "concur_reindex_ind5" -DETAIL: Key (c1)=(1) is duplicated. --- Reindexing concurrently this index fails with the same failure. --- The extra index created is itself invalid, and can be dropped. -REINDEX INDEX CONCURRENTLY concur_reindex_ind5; -ERROR: could not create unique index "concur_reindex_ind5_ccnew" -DETAIL: Key (c1)=(1) is duplicated. -\d concur_reindex_tab4 - Table "public.concur_reindex_tab4" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - c1 | integer | | | -Indexes: - "concur_reindex_ind5" UNIQUE, btree (c1) INVALID - "concur_reindex_ind5_ccnew" UNIQUE, btree (c1) INVALID - -DROP INDEX concur_reindex_ind5_ccnew; --- This makes the previous failure go away, so the index can become valid. -DELETE FROM concur_reindex_tab4 WHERE c1 = 1; --- The invalid index is not processed when running REINDEX TABLE. -REINDEX TABLE CONCURRENTLY concur_reindex_tab4; -WARNING: cannot reindex invalid index "public.concur_reindex_ind5" concurrently, skipping -NOTICE: table "concur_reindex_tab4" has no indexes that can be reindexed concurrently -\d concur_reindex_tab4 - Table "public.concur_reindex_tab4" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - c1 | integer | | | -Indexes: - "concur_reindex_ind5" UNIQUE, btree (c1) INVALID - --- But it is fixed with REINDEX INDEX. -REINDEX INDEX CONCURRENTLY concur_reindex_ind5; -\d concur_reindex_tab4 - Table "public.concur_reindex_tab4" - Column | Type | Collation | Nullable | Default ---------+---------+-----------+----------+--------- - c1 | integer | | | -Indexes: - "concur_reindex_ind5" UNIQUE, btree (c1) - -DROP TABLE concur_reindex_tab4; --- Check handling of indexes with expressions and predicates. The --- definitions of the rebuilt indexes should match the original --- definitions. -CREATE TABLE concur_exprs_tab (c1 int , c2 boolean); -INSERT INTO concur_exprs_tab (c1, c2) VALUES (1369652450, FALSE), - (414515746, TRUE), - (897778963, FALSE); -CREATE UNIQUE INDEX concur_exprs_index_expr - ON concur_exprs_tab ((c1::text COLLATE "C")); -CREATE UNIQUE INDEX concur_exprs_index_pred ON concur_exprs_tab (c1) - WHERE (c1::text > 500000000::text COLLATE "C"); -CREATE UNIQUE INDEX concur_exprs_index_pred_2 - ON concur_exprs_tab ((1 / c1)) - WHERE ('-H') >= (c2::TEXT) COLLATE "C"; -ALTER INDEX concur_exprs_index_expr ALTER COLUMN 1 SET STATISTICS 100; -ANALYZE concur_exprs_tab; -SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN ( - 'concur_exprs_index_expr'::regclass, - 'concur_exprs_index_pred'::regclass, - 'concur_exprs_index_pred_2'::regclass) - GROUP BY starelid ORDER BY starelid::regclass::text; - starelid | count --------------------------+------- - concur_exprs_index_expr | 1 -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); - pg_get_indexdef ---------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); - pg_get_indexdef ----------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); - pg_get_indexdef --------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= ((c2)::text COLLATE "C")) -(1 row) - -REINDEX TABLE CONCURRENTLY concur_exprs_tab; -SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); - pg_get_indexdef ---------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); - pg_get_indexdef ----------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); - pg_get_indexdef --------------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= ((c2)::text COLLATE "C")) -(1 row) - --- ALTER TABLE recreates the indexes, which should keep their collations. -ALTER TABLE concur_exprs_tab ALTER c2 TYPE TEXT; -SELECT pg_get_indexdef('concur_exprs_index_expr'::regclass); - pg_get_indexdef ---------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_expr ON public.concur_exprs_tab USING btree (((c1)::text) COLLATE "C") -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred'::regclass); - pg_get_indexdef ----------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred ON public.concur_exprs_tab USING btree (c1) WHERE ((c1)::text > ((500000000)::text COLLATE "C")) -(1 row) - -SELECT pg_get_indexdef('concur_exprs_index_pred_2'::regclass); - pg_get_indexdef ------------------------------------------------------------------------------------------------------------------------------------------- - CREATE UNIQUE INDEX concur_exprs_index_pred_2 ON public.concur_exprs_tab USING btree (((1 / c1))) WHERE ('-H'::text >= (c2 COLLATE "C")) -(1 row) - --- Statistics should remain intact. -SELECT starelid::regclass, count(*) FROM pg_statistic WHERE starelid IN ( - 'concur_exprs_index_expr'::regclass, - 'concur_exprs_index_pred'::regclass, - 'concur_exprs_index_pred_2'::regclass) - GROUP BY starelid ORDER BY starelid::regclass::text; - starelid | count --------------------------+------- - concur_exprs_index_expr | 1 -(1 row) - --- attstattarget should remain intact -SELECT attrelid::regclass, attnum, attstattarget - FROM pg_attribute WHERE attrelid IN ( - 'concur_exprs_index_expr'::regclass, - 'concur_exprs_index_pred'::regclass, - 'concur_exprs_index_pred_2'::regclass) - ORDER BY attrelid::regclass::text, attnum; - attrelid | attnum | attstattarget ----------------------------+--------+--------------- - concur_exprs_index_expr | 1 | 100 - concur_exprs_index_pred | 1 | -1 - concur_exprs_index_pred_2 | 1 | -1 -(3 rows) - -DROP TABLE concur_exprs_tab; --- Temporary tables and on-commit actions, where CONCURRENTLY is ignored. --- ON COMMIT PRESERVE ROWS, the default. -CREATE TEMP TABLE concur_temp_tab_1 (c1 int, c2 text) - ON COMMIT PRESERVE ROWS; -INSERT INTO concur_temp_tab_1 VALUES (1, 'foo'), (2, 'bar'); -CREATE INDEX concur_temp_ind_1 ON concur_temp_tab_1(c2); -REINDEX TABLE CONCURRENTLY concur_temp_tab_1; -REINDEX INDEX CONCURRENTLY concur_temp_ind_1; --- Still fails in transaction blocks -BEGIN; -REINDEX INDEX CONCURRENTLY concur_temp_ind_1; -ERROR: REINDEX CONCURRENTLY cannot run inside a transaction block -COMMIT; --- ON COMMIT DELETE ROWS -CREATE TEMP TABLE concur_temp_tab_2 (c1 int, c2 text) - ON COMMIT DELETE ROWS; -CREATE INDEX concur_temp_ind_2 ON concur_temp_tab_2(c2); -REINDEX TABLE CONCURRENTLY concur_temp_tab_2; -REINDEX INDEX CONCURRENTLY concur_temp_ind_2; --- ON COMMIT DROP -BEGIN; -CREATE TEMP TABLE concur_temp_tab_3 (c1 int, c2 text) - ON COMMIT PRESERVE ROWS; -INSERT INTO concur_temp_tab_3 VALUES (1, 'foo'), (2, 'bar'); -CREATE INDEX concur_temp_ind_3 ON concur_temp_tab_3(c2); --- Fails when running in a transaction -REINDEX INDEX CONCURRENTLY concur_temp_ind_3; -ERROR: REINDEX CONCURRENTLY cannot run inside a transaction block -COMMIT; --- REINDEX SCHEMA processes all temporary relations -CREATE TABLE reindex_temp_before AS -SELECT oid, relname, relfilenode, relkind, reltoastrelid - FROM pg_class - WHERE relname IN ('concur_temp_ind_1', 'concur_temp_ind_2'); -SELECT pg_my_temp_schema()::regnamespace as temp_schema_name \gset -REINDEX SCHEMA CONCURRENTLY :temp_schema_name; -SELECT b.relname, - b.relkind, - CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' - ELSE 'relfilenode has changed' END - FROM reindex_temp_before b JOIN pg_class a ON b.oid = a.oid - ORDER BY 1; - relname | relkind | case --------------------+---------+------------------------- - concur_temp_ind_1 | i | relfilenode has changed - concur_temp_ind_2 | i | relfilenode has changed -(2 rows) - -DROP TABLE concur_temp_tab_1, concur_temp_tab_2, reindex_temp_before; --- --- REINDEX SCHEMA --- -REINDEX SCHEMA schema_to_reindex; -- failure, schema does not exist -ERROR: schema "schema_to_reindex" does not exist -CREATE SCHEMA schema_to_reindex; -SET search_path = 'schema_to_reindex'; -CREATE TABLE table1(col1 SERIAL PRIMARY KEY); -INSERT INTO table1 SELECT generate_series(1,400); -CREATE TABLE table2(col1 SERIAL PRIMARY KEY, col2 TEXT NOT NULL); -INSERT INTO table2 SELECT generate_series(1,400), 'abc'; -CREATE INDEX ON table2(col2); -CREATE MATERIALIZED VIEW matview AS SELECT col1 FROM table2; -CREATE INDEX ON matview(col1); -CREATE VIEW view AS SELECT col2 FROM table2; -CREATE TABLE reindex_before AS -SELECT oid, relname, relfilenode, relkind, reltoastrelid - FROM pg_class - where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); -INSERT INTO reindex_before -SELECT oid, 'pg_toast_TABLE', relfilenode, relkind, reltoastrelid -FROM pg_class WHERE oid IN - (SELECT reltoastrelid FROM reindex_before WHERE reltoastrelid > 0); -INSERT INTO reindex_before -SELECT oid, 'pg_toast_TABLE_index', relfilenode, relkind, reltoastrelid -FROM pg_class where oid in - (select indexrelid from pg_index where indrelid in - (select reltoastrelid from reindex_before where reltoastrelid > 0)); -REINDEX SCHEMA schema_to_reindex; -CREATE TABLE reindex_after AS SELECT oid, relname, relfilenode, relkind - FROM pg_class - where relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'schema_to_reindex'); -SELECT b.relname, - b.relkind, - CASE WHEN a.relfilenode = b.relfilenode THEN 'relfilenode is unchanged' - ELSE 'relfilenode has changed' END - FROM reindex_before b JOIN pg_class a ON b.oid = a.oid - ORDER BY 1; - relname | relkind | case -----------------------+---------+-------------------------- - matview | m | relfilenode is unchanged - matview_col1_idx | i | relfilenode has changed - pg_toast_TABLE | t | relfilenode is unchanged - pg_toast_TABLE_index | i | relfilenode has changed - table1 | r | relfilenode is unchanged - table1_col1_seq | S | relfilenode is unchanged - table1_pkey | i | relfilenode has changed - table2 | r | relfilenode is unchanged - table2_col1_seq | S | relfilenode is unchanged - table2_col2_idx | i | relfilenode has changed - table2_pkey | i | relfilenode has changed - view | v | relfilenode is unchanged -(12 rows) - -REINDEX SCHEMA schema_to_reindex; -BEGIN; -REINDEX SCHEMA schema_to_reindex; -- failure, cannot run in a transaction -ERROR: REINDEX SCHEMA cannot run inside a transaction block -END; --- concurrently -REINDEX SCHEMA CONCURRENTLY schema_to_reindex; --- Failure for unauthorized user -CREATE ROLE regress_reindexuser NOLOGIN; -SET SESSION ROLE regress_reindexuser; -REINDEX SCHEMA schema_to_reindex; -ERROR: must be owner of schema schema_to_reindex --- Permission failures with toast tables and indexes (pg_authid here) -RESET ROLE; -GRANT USAGE ON SCHEMA pg_toast TO regress_reindexuser; -SET SESSION ROLE regress_reindexuser; -REINDEX TABLE pg_toast.pg_toast_1260; -ERROR: must be owner of table pg_toast_1260 -REINDEX INDEX pg_toast.pg_toast_1260_index; -ERROR: must be owner of index pg_toast_1260_index --- Clean up -RESET ROLE; -REVOKE USAGE ON SCHEMA pg_toast FROM regress_reindexuser; -DROP ROLE regress_reindexuser; -DROP SCHEMA schema_to_reindex CASCADE; -NOTICE: drop cascades to 6 other objects -DETAIL: drop cascades to table table1 -drop cascades to table table2 -drop cascades to materialized view matview -drop cascades to view view -drop cascades to table reindex_before -drop cascades to table reindex_after +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/create_index_spgist.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/create_index_spgist.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/create_index_spgist.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/create_index_spgist.out 2022-02-13 01:12:08.485491158 +0100 @@ -342,968 +342,8 @@ SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN quad_point_tbl_ord_idx1 idx ON seq.n = idx.n WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ------------------------------------------------------------ - WindowAgg - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) - Order By: (p <-> '(0,0)'::point) -(4 rows) - -CREATE TEMP TABLE quad_point_tbl_ord_idx2 AS -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN quad_point_tbl_ord_idx2 idx -ON seq.n = idx.n -WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p -FROM quad_point_tbl WHERE p IS NOT NULL; - QUERY PLAN ------------------------------------------------------------ - WindowAgg - -> Index Only Scan using sp_quad_ind on quad_point_tbl - Index Cond: (p IS NOT NULL) - Order By: (p <-> '(333,400)'::point) -(4 rows) - -CREATE TEMP TABLE quad_point_tbl_ord_idx3 AS -SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p -FROM quad_point_tbl WHERE p IS NOT NULL; -SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN quad_point_tbl_ord_idx3 idx -ON seq.n = idx.n -WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p << '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p >> '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p >^ '(5000,4000)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p ~= '(4585,365)'::point) -(3 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM kd_point_tbl; - QUERY PLAN -------------------------------------------------------- - WindowAgg - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Order By: (p <-> '(0,0)'::point) -(3 rows) - -CREATE TEMP TABLE kd_point_tbl_ord_idx1 AS -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM kd_point_tbl; -SELECT * FROM quad_point_tbl_ord_seq1 seq FULL JOIN kd_point_tbl_ord_idx1 idx -ON seq.n = idx.n -WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------- - WindowAgg - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p <@ '(1000,1000),(200,200)'::box) - Order By: (p <-> '(0,0)'::point) -(4 rows) - -CREATE TEMP TABLE kd_point_tbl_ord_idx2 AS -SELECT row_number() OVER (ORDER BY p <-> '0,0') n, p <-> '0,0' dist, p -FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; -SELECT * FROM quad_point_tbl_ord_seq2 seq FULL JOIN kd_point_tbl_ord_idx2 idx -ON seq.n = idx.n -WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - -EXPLAIN (COSTS OFF) -SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p -FROM kd_point_tbl WHERE p IS NOT NULL; - QUERY PLAN -------------------------------------------------------- - WindowAgg - -> Index Only Scan using sp_kd_ind on kd_point_tbl - Index Cond: (p IS NOT NULL) - Order By: (p <-> '(333,400)'::point) -(4 rows) - -CREATE TEMP TABLE kd_point_tbl_ord_idx3 AS -SELECT row_number() OVER (ORDER BY p <-> '333,400') n, p <-> '333,400' dist, p -FROM kd_point_tbl WHERE p IS NOT NULL; -SELECT * FROM quad_point_tbl_ord_seq3 seq FULL JOIN kd_point_tbl_ord_idx3 idx -ON seq.n = idx.n -WHERE seq.dist IS DISTINCT FROM idx.dist; - n | dist | p | n | dist | p ----+------+---+---+------+--- -(0 rows) - --- check ORDER BY distance to NULL -SELECT (SELECT p FROM kd_point_tbl ORDER BY p <-> pt, p <-> '0,0' LIMIT 1) -FROM (VALUES (point '1,2'), (NULL), ('1234,5678')) pts(pt); - p -------------- - (59,21) - (59,21) - (1239,5647) -(3 rows) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcdef'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - count -------- - 1000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcde'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'P0123456789abcdefF'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t < 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~<~ 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t <= 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - QUERY PLAN -------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~<=~ 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'Aztec Ct '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t = 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - count -------- - 2 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------ - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t >= 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - QUERY PLAN -------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~>=~ 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t > 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ~>~ 'Worth St '::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Index Only Scan using sp_radix_ind on radix_text_tbl - Index Cond: (t ^@ 'Worth'::text) -(3 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - count -------- - 2 -(1 row) - --- Now check the results from bitmap indexscan -SET enable_seqscan = OFF; -SET enable_indexscan = OFF; -SET enable_bitmapscan = ON; -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p IS NULL) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p IS NULL) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NULL; - count -------- - 3 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p IS NOT NULL) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p IS NOT NULL) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p IS NOT NULL; - count -------- - 11000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl; - QUERY PLAN ----------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - -> Bitmap Index Scan on sp_quad_ind -(3 rows) - -SELECT count(*) FROM quad_point_tbl; - count -------- - 11003 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: ('(1000,1000),(200,200)'::box @> p) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p << '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p << '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p >> '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p >> '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p <^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p <^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p >^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p >^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on quad_point_tbl - Recheck Cond: (p ~= '(4585,365)'::point) - -> Bitmap Index Scan on sp_quad_ind - Index Cond: (p ~= '(4585,365)'::point) -(5 rows) - -SELECT count(*) FROM quad_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p <@ '(1000,1000),(200,200)'::box) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <@ box '(200,200,1000,1000)'; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - QUERY PLAN ---------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: ('(1000,1000),(200,200)'::box @> p) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p <@ '(1000,1000),(200,200)'::box) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE box '(200,200,1000,1000)' @> p; - count -------- - 1057 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p << '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p << '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p << '(5000, 4000)'; - count -------- - 6000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p >> '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p >> '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >> '(5000, 4000)'; - count -------- - 4999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p <^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p <^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p <^ '(5000, 4000)'; - count -------- - 5000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p >^ '(5000,4000)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p >^ '(5000,4000)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p >^ '(5000, 4000)'; - count -------- - 5999 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - QUERY PLAN ------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on kd_point_tbl - Recheck Cond: (p ~= '(4585,365)'::point) - -> Bitmap Index Scan on sp_kd_ind - Index Cond: (p ~= '(4585,365)'::point) -(5 rows) - -SELECT count(*) FROM kd_point_tbl WHERE p ~= '(4585, 365)'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - QUERY PLAN ------------------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcdef'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcdef'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdef'; - count -------- - 1000 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - QUERY PLAN ----------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcde'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcde'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcde'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'P0123456789abcdefF'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'P0123456789abcdefF'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'P0123456789abcdefF'; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t < 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t < 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t < 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~<~ 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~<~ 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<~ 'Aztec Ct '; - count -------- - 272 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - QUERY PLAN ------------------------------------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t <= 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t <= 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t <= 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - QUERY PLAN -------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~<=~ 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~<=~ 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~<=~ 'Aztec Ct '; - count -------- - 273 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'Aztec Ct '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'Aztec Ct '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Aztec Ct '; - count -------- - 1 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t = 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t = 'Worth St '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t = 'Worth St '; - count -------- - 2 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t >= 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t >= 'Worth St '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t >= 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - QUERY PLAN -------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~>=~ 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~>=~ 'Worth St '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>=~ 'Worth St '; - count -------- - 50 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - QUERY PLAN ----------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t > 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t > 'Worth St '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t > 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - QUERY PLAN ------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ~>~ 'Worth St '::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ~>~ 'Worth St '::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ~>~ 'Worth St '; - count -------- - 48 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - QUERY PLAN ------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on radix_text_tbl - Recheck Cond: (t ^@ 'Worth'::text) - -> Bitmap Index Scan on sp_radix_ind - Index Cond: (t ^@ 'Worth'::text) -(5 rows) - -SELECT count(*) FROM radix_text_tbl WHERE t ^@ 'Worth'; - count -------- - 2 -(1 row) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/select.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/select.out 2022-02-13 01:12:09.742159946 +0100 @@ -926,41 +926,8 @@ (4 rows) select sillysrf(-1) order by 1; - sillysrf ----------- - -1 - 1 - 2 - 10 -(4 rows) - -drop function sillysrf(int); --- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict --- (see bug #5084) -select * from (values (2),(null),(1)) v(k) where k = k order by k; - k ---- - 1 - 2 -(2 rows) - -select * from (values (2),(null),(1)) v(k) where k = k; - k ---- - 2 - 1 -(2 rows) - --- Test partitioned tables with no partitions, which should be handled the --- same as the non-inheritance case when expanding its RTE. -create table list_parted_tbl (a int,b int) partition by list (a); -create table list_parted_tbl1 partition of list_parted_tbl - for values in (1) partition by list(b); -explain (costs off) select * from list_parted_tbl; - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - -drop table list_parted_tbl; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/inherit.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/inherit.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/inherit.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/inherit.out 2022-02-13 01:12:10.562161330 +0100 @@ -1460,1075 +1460,8 @@ set enable_seqscan = off; -- plan with fewest seqscans should be merge set enable_parallel_append = off; -- Don't let parallel-append interfere explain (verbose, costs off) select * from matest0 order by 1-id; - QUERY PLAN ------------------------------------------------------------------------- - Merge Append - Sort Key: ((1 - matest0.id)) - -> Index Scan using matest0i on public.matest0 matest0_1 - Output: matest0_1.id, matest0_1.name, (1 - matest0_1.id) - -> Index Scan using matest1i on public.matest1 matest0_2 - Output: matest0_2.id, matest0_2.name, (1 - matest0_2.id) - -> Sort - Output: matest0_3.id, matest0_3.name, ((1 - matest0_3.id)) - Sort Key: ((1 - matest0_3.id)) - -> Seq Scan on public.matest2 matest0_3 - Output: matest0_3.id, matest0_3.name, (1 - matest0_3.id) - -> Index Scan using matest3i on public.matest3 matest0_4 - Output: matest0_4.id, matest0_4.name, (1 - matest0_4.id) -(13 rows) - -select * from matest0 order by 1-id; - id | name -----+-------- - 6 | Test 6 - 5 | Test 5 - 4 | Test 4 - 3 | Test 3 - 2 | Test 2 - 1 | Test 1 -(6 rows) - -explain (verbose, costs off) select min(1-id) from matest0; - QUERY PLAN ---------------------------------------------------------------------------------- - Result - Output: $0 - InitPlan 1 (returns $0) - -> Limit - Output: ((1 - matest0.id)) - -> Result - Output: ((1 - matest0.id)) - -> Merge Append - Sort Key: ((1 - matest0.id)) - -> Index Scan using matest0i on public.matest0 matest0_1 - Output: matest0_1.id, (1 - matest0_1.id) - Index Cond: ((1 - matest0_1.id) IS NOT NULL) - -> Index Scan using matest1i on public.matest1 matest0_2 - Output: matest0_2.id, (1 - matest0_2.id) - Index Cond: ((1 - matest0_2.id) IS NOT NULL) - -> Sort - Output: matest0_3.id, ((1 - matest0_3.id)) - Sort Key: ((1 - matest0_3.id)) - -> Bitmap Heap Scan on public.matest2 matest0_3 - Output: matest0_3.id, (1 - matest0_3.id) - Filter: ((1 - matest0_3.id) IS NOT NULL) - -> Bitmap Index Scan on matest2_pkey - -> Index Scan using matest3i on public.matest3 matest0_4 - Output: matest0_4.id, (1 - matest0_4.id) - Index Cond: ((1 - matest0_4.id) IS NOT NULL) -(25 rows) - -select min(1-id) from matest0; - min ------ - -5 -(1 row) - -reset enable_seqscan; -reset enable_parallel_append; -drop table matest0 cascade; -NOTICE: drop cascades to 3 other objects -DETAIL: drop cascades to table matest1 -drop cascades to table matest2 -drop cascades to table matest3 --- --- Check that use of an index with an extraneous column doesn't produce --- a plan with extraneous sorting --- -create table matest0 (a int, b int, c int, d int); -create table matest1 () inherits(matest0); -create index matest0i on matest0 (b, c); -create index matest1i on matest1 (b, c); -set enable_nestloop = off; -- we want a plan with two MergeAppends -explain (costs off) -select t1.* from matest0 t1, matest0 t2 -where t1.b = t2.b and t2.c = t2.d -order by t1.b limit 10; - QUERY PLAN -------------------------------------------------------------------- - Limit - -> Merge Join - Merge Cond: (t1.b = t2.b) - -> Merge Append - Sort Key: t1.b - -> Index Scan using matest0i on matest0 t1_1 - -> Index Scan using matest1i on matest1 t1_2 - -> Materialize - -> Merge Append - Sort Key: t2.b - -> Index Scan using matest0i on matest0 t2_1 - Filter: (c = d) - -> Index Scan using matest1i on matest1 t2_2 - Filter: (c = d) -(14 rows) - -reset enable_nestloop; -drop table matest0 cascade; -NOTICE: drop cascades to table matest1 --- --- Test merge-append for UNION ALL append relations --- -set enable_seqscan = off; -set enable_indexscan = on; -set enable_bitmapscan = off; --- Check handling of duplicated, constant, or volatile targetlist items -explain (costs off) -SELECT thousand, tenthous FROM tenk1 -UNION ALL -SELECT thousand, thousand FROM tenk1 -ORDER BY thousand, tenthous; - QUERY PLAN -------------------------------------------------------------------------- - Merge Append - Sort Key: tenk1.thousand, tenk1.tenthous - -> Index Only Scan using tenk1_thous_tenthous on tenk1 - -> Sort - Sort Key: tenk1_1.thousand, tenk1_1.thousand - -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1 -(6 rows) - -explain (costs off) -SELECT thousand, tenthous, thousand+tenthous AS x FROM tenk1 -UNION ALL -SELECT 42, 42, hundred FROM tenk1 -ORDER BY thousand, tenthous; - QUERY PLAN ------------------------------------------------------------------- - Merge Append - Sort Key: tenk1.thousand, tenk1.tenthous - -> Index Only Scan using tenk1_thous_tenthous on tenk1 - -> Sort - Sort Key: 42, 42 - -> Index Only Scan using tenk1_hundred on tenk1 tenk1_1 -(6 rows) - -explain (costs off) -SELECT thousand, tenthous FROM tenk1 -UNION ALL -SELECT thousand, random()::integer FROM tenk1 -ORDER BY thousand, tenthous; - QUERY PLAN -------------------------------------------------------------------------- - Merge Append - Sort Key: tenk1.thousand, tenk1.tenthous - -> Index Only Scan using tenk1_thous_tenthous on tenk1 - -> Sort - Sort Key: tenk1_1.thousand, ((random())::integer) - -> Index Only Scan using tenk1_thous_tenthous on tenk1 tenk1_1 -(6 rows) - --- Check min/max aggregate optimization -explain (costs off) -SELECT min(x) FROM - (SELECT unique1 AS x FROM tenk1 a - UNION ALL - SELECT unique2 AS x FROM tenk1 b) s; - QUERY PLAN --------------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Merge Append - Sort Key: a.unique1 - -> Index Only Scan using tenk1_unique1 on tenk1 a - Index Cond: (unique1 IS NOT NULL) - -> Index Only Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 IS NOT NULL) -(9 rows) - -explain (costs off) -SELECT min(y) FROM - (SELECT unique1 AS x, unique1 AS y FROM tenk1 a - UNION ALL - SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s; - QUERY PLAN --------------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Merge Append - Sort Key: a.unique1 - -> Index Only Scan using tenk1_unique1 on tenk1 a - Index Cond: (unique1 IS NOT NULL) - -> Index Only Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 IS NOT NULL) -(9 rows) - --- XXX planner doesn't recognize that index on unique2 is sufficiently sorted -explain (costs off) -SELECT x, y FROM - (SELECT thousand AS x, tenthous AS y FROM tenk1 a - UNION ALL - SELECT unique2 AS x, unique2 AS y FROM tenk1 b) s -ORDER BY x, y; - QUERY PLAN -------------------------------------------------------------- - Merge Append - Sort Key: a.thousand, a.tenthous - -> Index Only Scan using tenk1_thous_tenthous on tenk1 a - -> Sort - Sort Key: b.unique2, b.unique2 - -> Index Only Scan using tenk1_unique2 on tenk1 b -(6 rows) - --- exercise rescan code path via a repeatedly-evaluated subquery -explain (costs off) -SELECT - ARRAY(SELECT f.i FROM ( - (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1) - UNION ALL - (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1) - ) f(i) - ORDER BY f.i LIMIT 10) -FROM generate_series(1, 3) g(i); - QUERY PLAN ----------------------------------------------------------------- - Function Scan on generate_series g - SubPlan 1 - -> Limit - -> Merge Append - Sort Key: ((d.d + g.i)) - -> Sort - Sort Key: ((d.d + g.i)) - -> Function Scan on generate_series d - -> Sort - Sort Key: ((d_1.d + g.i)) - -> Function Scan on generate_series d_1 -(11 rows) - -SELECT - ARRAY(SELECT f.i FROM ( - (SELECT d + g.i FROM generate_series(4, 30, 3) d ORDER BY 1) - UNION ALL - (SELECT d + g.i FROM generate_series(0, 30, 5) d ORDER BY 1) - ) f(i) - ORDER BY f.i LIMIT 10) -FROM generate_series(1, 3) g(i); - array ------------------------------- - {1,5,6,8,11,11,14,16,17,20} - {2,6,7,9,12,12,15,17,18,21} - {3,7,8,10,13,13,16,18,19,22} -(3 rows) - -reset enable_seqscan; -reset enable_indexscan; -reset enable_bitmapscan; --- --- Check handling of a constant-null CHECK constraint --- -create table cnullparent (f1 int); -create table cnullchild (check (f1 = 1 or f1 = null)) inherits(cnullparent); -insert into cnullchild values(1); -insert into cnullchild values(2); -insert into cnullchild values(null); -select * from cnullparent; - f1 ----- - 1 - 2 - -(3 rows) - -select * from cnullparent where f1 = 2; - f1 ----- - 2 -(1 row) - -drop table cnullparent cascade; -NOTICE: drop cascades to table cnullchild --- --- Check use of temporary tables with inheritance trees --- -create table inh_perm_parent (a1 int); -create temp table inh_temp_parent (a1 int); -create temp table inh_temp_child () inherits (inh_perm_parent); -- ok -create table inh_perm_child () inherits (inh_temp_parent); -- error -ERROR: cannot inherit from temporary relation "inh_temp_parent" -create temp table inh_temp_child_2 () inherits (inh_temp_parent); -- ok -insert into inh_perm_parent values (1); -insert into inh_temp_parent values (2); -insert into inh_temp_child values (3); -insert into inh_temp_child_2 values (4); -select tableoid::regclass, a1 from inh_perm_parent; - tableoid | a1 ------------------+---- - inh_perm_parent | 1 - inh_temp_child | 3 -(2 rows) - -select tableoid::regclass, a1 from inh_temp_parent; - tableoid | a1 -------------------+---- - inh_temp_parent | 2 - inh_temp_child_2 | 4 -(2 rows) - -drop table inh_perm_parent cascade; -NOTICE: drop cascades to table inh_temp_child -drop table inh_temp_parent cascade; -NOTICE: drop cascades to table inh_temp_child_2 --- --- Check that constraint exclusion works correctly with partitions using --- implicit constraints generated from the partition bound information. --- -create table list_parted ( - a varchar -) partition by list (a); -create table part_ab_cd partition of list_parted for values in ('ab', 'cd'); -create table part_ef_gh partition of list_parted for values in ('ef', 'gh'); -create table part_null_xy partition of list_parted for values in (null, 'xy'); -explain (costs off) select * from list_parted; - QUERY PLAN ----------------------------------------------- - Append - -> Seq Scan on part_ab_cd list_parted_1 - -> Seq Scan on part_ef_gh list_parted_2 - -> Seq Scan on part_null_xy list_parted_3 -(4 rows) - -explain (costs off) select * from list_parted where a is null; - QUERY PLAN --------------------------------------- - Seq Scan on part_null_xy list_parted - Filter: (a IS NULL) -(2 rows) - -explain (costs off) select * from list_parted where a is not null; - QUERY PLAN ----------------------------------------------- - Append - -> Seq Scan on part_ab_cd list_parted_1 - Filter: (a IS NOT NULL) - -> Seq Scan on part_ef_gh list_parted_2 - Filter: (a IS NOT NULL) - -> Seq Scan on part_null_xy list_parted_3 - Filter: (a IS NOT NULL) -(7 rows) - -explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); - QUERY PLAN ----------------------------------------------------------- - Append - -> Seq Scan on part_ab_cd list_parted_1 - Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[])) - -> Seq Scan on part_ef_gh list_parted_2 - Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[])) -(5 rows) - -explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd'); - QUERY PLAN ---------------------------------------------------------------------------------- - Seq Scan on part_ab_cd list_parted - Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) -(2 rows) - -explain (costs off) select * from list_parted where a = 'ab'; - QUERY PLAN ------------------------------------- - Seq Scan on part_ab_cd list_parted - Filter: ((a)::text = 'ab'::text) -(2 rows) - -create table range_list_parted ( - a int, - b char(2) -) partition by range (a); -create table part_1_10 partition of range_list_parted for values from (1) to (10) partition by list (b); -create table part_1_10_ab partition of part_1_10 for values in ('ab'); -create table part_1_10_cd partition of part_1_10 for values in ('cd'); -create table part_10_20 partition of range_list_parted for values from (10) to (20) partition by list (b); -create table part_10_20_ab partition of part_10_20 for values in ('ab'); -create table part_10_20_cd partition of part_10_20 for values in ('cd'); -create table part_21_30 partition of range_list_parted for values from (21) to (30) partition by list (b); -create table part_21_30_ab partition of part_21_30 for values in ('ab'); -create table part_21_30_cd partition of part_21_30 for values in ('cd'); -create table part_40_inf partition of range_list_parted for values from (40) to (maxvalue) partition by list (b); -create table part_40_inf_ab partition of part_40_inf for values in ('ab'); -create table part_40_inf_cd partition of part_40_inf for values in ('cd'); -create table part_40_inf_null partition of part_40_inf for values in (null); -explain (costs off) select * from range_list_parted; - QUERY PLAN --------------------------------------------------------- - Append - -> Seq Scan on part_1_10_ab range_list_parted_1 - -> Seq Scan on part_1_10_cd range_list_parted_2 - -> Seq Scan on part_10_20_ab range_list_parted_3 - -> Seq Scan on part_10_20_cd range_list_parted_4 - -> Seq Scan on part_21_30_ab range_list_parted_5 - -> Seq Scan on part_21_30_cd range_list_parted_6 - -> Seq Scan on part_40_inf_ab range_list_parted_7 - -> Seq Scan on part_40_inf_cd range_list_parted_8 - -> Seq Scan on part_40_inf_null range_list_parted_9 -(10 rows) - -explain (costs off) select * from range_list_parted where a = 5; - QUERY PLAN ----------------------------------------------------- - Append - -> Seq Scan on part_1_10_ab range_list_parted_1 - Filter: (a = 5) - -> Seq Scan on part_1_10_cd range_list_parted_2 - Filter: (a = 5) -(5 rows) - -explain (costs off) select * from range_list_parted where b = 'ab'; - QUERY PLAN ------------------------------------------------------- - Append - -> Seq Scan on part_1_10_ab range_list_parted_1 - Filter: (b = 'ab'::bpchar) - -> Seq Scan on part_10_20_ab range_list_parted_2 - Filter: (b = 'ab'::bpchar) - -> Seq Scan on part_21_30_ab range_list_parted_3 - Filter: (b = 'ab'::bpchar) - -> Seq Scan on part_40_inf_ab range_list_parted_4 - Filter: (b = 'ab'::bpchar) -(9 rows) - -explain (costs off) select * from range_list_parted where a between 3 and 23 and b in ('ab'); - QUERY PLAN ------------------------------------------------------------------ - Append - -> Seq Scan on part_1_10_ab range_list_parted_1 - Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar)) - -> Seq Scan on part_10_20_ab range_list_parted_2 - Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar)) - -> Seq Scan on part_21_30_ab range_list_parted_3 - Filter: ((a >= 3) AND (a <= 23) AND (b = 'ab'::bpchar)) -(7 rows) - -/* Should select no rows because range partition key cannot be null */ -explain (costs off) select * from range_list_parted where a is null; - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - -/* Should only select rows from the null-accepting partition */ -explain (costs off) select * from range_list_parted where b is null; - QUERY PLAN ------------------------------------------------- - Seq Scan on part_40_inf_null range_list_parted - Filter: (b IS NULL) -(2 rows) - -explain (costs off) select * from range_list_parted where a is not null and a < 67; - QUERY PLAN --------------------------------------------------------- - Append - -> Seq Scan on part_1_10_ab range_list_parted_1 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_1_10_cd range_list_parted_2 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_10_20_ab range_list_parted_3 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_10_20_cd range_list_parted_4 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_21_30_ab range_list_parted_5 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_21_30_cd range_list_parted_6 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_40_inf_ab range_list_parted_7 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_40_inf_cd range_list_parted_8 - Filter: ((a IS NOT NULL) AND (a < 67)) - -> Seq Scan on part_40_inf_null range_list_parted_9 - Filter: ((a IS NOT NULL) AND (a < 67)) -(19 rows) - -explain (costs off) select * from range_list_parted where a >= 30; - QUERY PLAN --------------------------------------------------------- - Append - -> Seq Scan on part_40_inf_ab range_list_parted_1 - Filter: (a >= 30) - -> Seq Scan on part_40_inf_cd range_list_parted_2 - Filter: (a >= 30) - -> Seq Scan on part_40_inf_null range_list_parted_3 - Filter: (a >= 30) -(7 rows) - -drop table list_parted; -drop table range_list_parted; --- check that constraint exclusion is able to cope with the partition --- constraint emitted for multi-column range partitioned tables -create table mcrparted (a int, b int, c int) partition by range (a, abs(b), c); -create table mcrparted_def partition of mcrparted default; -create table mcrparted0 partition of mcrparted for values from (minvalue, minvalue, minvalue) to (1, 1, 1); -create table mcrparted1 partition of mcrparted for values from (1, 1, 1) to (10, 5, 10); -create table mcrparted2 partition of mcrparted for values from (10, 5, 10) to (10, 10, 10); -create table mcrparted3 partition of mcrparted for values from (11, 1, 1) to (20, 10, 10); -create table mcrparted4 partition of mcrparted for values from (20, 10, 10) to (20, 20, 20); -create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue); -explain (costs off) select * from mcrparted where a = 0; -- scans mcrparted0, mcrparted_def - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted0 mcrparted_1 - Filter: (a = 0) - -> Seq Scan on mcrparted_def mcrparted_2 - Filter: (a = 0) -(5 rows) - -explain (costs off) select * from mcrparted where a = 10 and abs(b) < 5; -- scans mcrparted1, mcrparted_def - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted1 mcrparted_1 - Filter: ((a = 10) AND (abs(b) < 5)) - -> Seq Scan on mcrparted_def mcrparted_2 - Filter: ((a = 10) AND (abs(b) < 5)) -(5 rows) - -explain (costs off) select * from mcrparted where a = 10 and abs(b) = 5; -- scans mcrparted1, mcrparted2, mcrparted_def - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted1 mcrparted_1 - Filter: ((a = 10) AND (abs(b) = 5)) - -> Seq Scan on mcrparted2 mcrparted_2 - Filter: ((a = 10) AND (abs(b) = 5)) - -> Seq Scan on mcrparted_def mcrparted_3 - Filter: ((a = 10) AND (abs(b) = 5)) -(7 rows) - -explain (costs off) select * from mcrparted where abs(b) = 5; -- scans all partitions - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted0 mcrparted_1 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted1 mcrparted_2 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted2 mcrparted_3 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted3 mcrparted_4 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted4 mcrparted_5 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted5 mcrparted_6 - Filter: (abs(b) = 5) - -> Seq Scan on mcrparted_def mcrparted_7 - Filter: (abs(b) = 5) -(15 rows) - -explain (costs off) select * from mcrparted where a > -1; -- scans all partitions - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted0 mcrparted_1 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted1 mcrparted_2 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted2 mcrparted_3 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted3 mcrparted_4 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted4 mcrparted_5 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted5 mcrparted_6 - Filter: (a > '-1'::integer) - -> Seq Scan on mcrparted_def mcrparted_7 - Filter: (a > '-1'::integer) -(15 rows) - -explain (costs off) select * from mcrparted where a = 20 and abs(b) = 10 and c > 10; -- scans mcrparted4 - QUERY PLAN ------------------------------------------------------ - Seq Scan on mcrparted4 mcrparted - Filter: ((c > 10) AND (a = 20) AND (abs(b) = 10)) -(2 rows) - -explain (costs off) select * from mcrparted where a = 20 and c > 20; -- scans mcrparted3, mcrparte4, mcrparte5, mcrparted_def - QUERY PLAN ---------------------------------------------- - Append - -> Seq Scan on mcrparted3 mcrparted_1 - Filter: ((c > 20) AND (a = 20)) - -> Seq Scan on mcrparted4 mcrparted_2 - Filter: ((c > 20) AND (a = 20)) - -> Seq Scan on mcrparted5 mcrparted_3 - Filter: ((c > 20) AND (a = 20)) - -> Seq Scan on mcrparted_def mcrparted_4 - Filter: ((c > 20) AND (a = 20)) -(9 rows) - --- check that partitioned table Appends cope with being referenced in --- subplans -create table parted_minmax (a int, b varchar(16)) partition by range (a); -create table parted_minmax1 partition of parted_minmax for values from (1) to (10); -create index parted_minmax1i on parted_minmax1 (a, b); -insert into parted_minmax values (1,'12345'); -explain (costs off) select min(a), max(a) from parted_minmax where b = '12345'; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Index Only Scan using parted_minmax1i on parted_minmax1 parted_minmax - Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) - InitPlan 2 (returns $1) - -> Limit - -> Index Only Scan Backward using parted_minmax1i on parted_minmax1 parted_minmax_1 - Index Cond: ((a IS NOT NULL) AND (b = '12345'::text)) -(9 rows) - -select min(a), max(a) from parted_minmax where b = '12345'; - min | max ------+----- - 1 | 1 -(1 row) - -drop table parted_minmax; --- Test code that uses Append nodes in place of MergeAppend when the --- partition ordering matches the desired ordering. -create index mcrparted_a_abs_c_idx on mcrparted (a, abs(b), c); --- MergeAppend must be used when a default partition exists -explain (costs off) select * from mcrparted order by a, abs(b), c; - QUERY PLAN -------------------------------------------------------------------------------- - Merge Append - Sort Key: mcrparted.a, (abs(mcrparted.b)), mcrparted.c - -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5 - -> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6 - -> Index Scan using mcrparted_def_a_abs_c_idx on mcrparted_def mcrparted_7 -(9 rows) - -drop table mcrparted_def; --- Append is used for a RANGE partitioned table with no default --- and no subpartitions -explain (costs off) select * from mcrparted order by a, abs(b), c; - QUERY PLAN -------------------------------------------------------------------------- - Append - -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5 - -> Index Scan using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6 -(7 rows) - --- Append is used with subpaths in reverse order with backwards index scans -explain (costs off) select * from mcrparted order by a desc, abs(b) desc, c desc; - QUERY PLAN ----------------------------------------------------------------------------------- - Append - -> Index Scan Backward using mcrparted5_a_abs_c_idx on mcrparted5 mcrparted_6 - -> Index Scan Backward using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5 - -> Index Scan Backward using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - -> Index Scan Backward using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - -> Index Scan Backward using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - -> Index Scan Backward using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 -(7 rows) - --- check that Append plan is used containing a MergeAppend for sub-partitions --- that are unordered. -drop table mcrparted5; -create table mcrparted5 partition of mcrparted for values from (20, 20, 20) to (maxvalue, maxvalue, maxvalue) partition by list (a); -create table mcrparted5a partition of mcrparted5 for values in(20); -create table mcrparted5_def partition of mcrparted5 default; -explain (costs off) select * from mcrparted order by a, abs(b), c; - QUERY PLAN ---------------------------------------------------------------------------------------- - Append - -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5 - -> Merge Append - Sort Key: mcrparted_7.a, (abs(mcrparted_7.b)), mcrparted_7.c - -> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_7 - -> Index Scan using mcrparted5_def_a_abs_c_idx on mcrparted5_def mcrparted_8 -(10 rows) - -drop table mcrparted5_def; --- check that an Append plan is used and the sub-partitions are flattened --- into the main Append when the sub-partition is unordered but contains --- just a single sub-partition. -explain (costs off) select a, abs(b) from mcrparted order by a, abs(b), c; - QUERY PLAN ---------------------------------------------------------------------------- - Append - -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - -> Index Scan using mcrparted4_a_abs_c_idx on mcrparted4 mcrparted_5 - -> Index Scan using mcrparted5a_a_abs_c_idx on mcrparted5a mcrparted_6 -(7 rows) - --- check that Append is used when the sub-partitioned tables are pruned --- during planning. -explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c; - QUERY PLAN -------------------------------------------------------------------------- - Append - -> Index Scan using mcrparted0_a_abs_c_idx on mcrparted0 mcrparted_1 - Index Cond: (a < 20) - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - Index Cond: (a < 20) - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - Index Cond: (a < 20) - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - Index Cond: (a < 20) -(9 rows) - -create table mclparted (a int) partition by list(a); -create table mclparted1 partition of mclparted for values in(1); -create table mclparted2 partition of mclparted for values in(2); -create index on mclparted (a); --- Ensure an Append is used for a list partition with an order by. -explain (costs off) select * from mclparted order by a; - QUERY PLAN ------------------------------------------------------------------------- - Append - -> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted_1 - -> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_2 -(3 rows) - --- Ensure a MergeAppend is used when a partition exists with interleaved --- datums in the partition bound. -create table mclparted3_5 partition of mclparted for values in(3,5); -create table mclparted4 partition of mclparted for values in(4); -explain (costs off) select * from mclparted order by a; - QUERY PLAN ----------------------------------------------------------------------------- - Merge Append - Sort Key: mclparted.a - -> Index Only Scan using mclparted1_a_idx on mclparted1 mclparted_1 - -> Index Only Scan using mclparted2_a_idx on mclparted2 mclparted_2 - -> Index Only Scan using mclparted3_5_a_idx on mclparted3_5 mclparted_3 - -> Index Only Scan using mclparted4_a_idx on mclparted4 mclparted_4 -(6 rows) - -drop table mclparted; --- Ensure subplans which don't have a path with the correct pathkeys get --- sorted correctly. -drop index mcrparted_a_abs_c_idx; -create index on mcrparted1 (a, abs(b), c); -create index on mcrparted2 (a, abs(b), c); -create index on mcrparted3 (a, abs(b), c); -create index on mcrparted4 (a, abs(b), c); -explain (costs off) select * from mcrparted where a < 20 order by a, abs(b), c limit 1; - QUERY PLAN -------------------------------------------------------------------------------- - Limit - -> Append - -> Sort - Sort Key: mcrparted_1.a, (abs(mcrparted_1.b)), mcrparted_1.c - -> Seq Scan on mcrparted0 mcrparted_1 - Filter: (a < 20) - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_2 - Index Cond: (a < 20) - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_3 - Index Cond: (a < 20) - -> Index Scan using mcrparted3_a_abs_c_idx on mcrparted3 mcrparted_4 - Index Cond: (a < 20) -(12 rows) - -set enable_bitmapscan = 0; --- Ensure Append node can be used when the partition is ordered by some --- pathkeys which were deemed redundant. -explain (costs off) select * from mcrparted where a = 10 order by a, abs(b), c; - QUERY PLAN -------------------------------------------------------------------------- - Append - -> Index Scan using mcrparted1_a_abs_c_idx on mcrparted1 mcrparted_1 - Index Cond: (a = 10) - -> Index Scan using mcrparted2_a_abs_c_idx on mcrparted2 mcrparted_2 - Index Cond: (a = 10) -(5 rows) - -reset enable_bitmapscan; -drop table mcrparted; --- Ensure LIST partitions allow an Append to be used instead of a MergeAppend -create table bool_lp (b bool) partition by list(b); -create table bool_lp_true partition of bool_lp for values in(true); -create table bool_lp_false partition of bool_lp for values in(false); -create index on bool_lp (b); -explain (costs off) select * from bool_lp order by b; - QUERY PLAN ----------------------------------------------------------------------------- - Append - -> Index Only Scan using bool_lp_false_b_idx on bool_lp_false bool_lp_1 - -> Index Only Scan using bool_lp_true_b_idx on bool_lp_true bool_lp_2 -(3 rows) - -drop table bool_lp; --- Ensure const bool quals can be properly detected as redundant -create table bool_rp (b bool, a int) partition by range(b,a); -create table bool_rp_false_1k partition of bool_rp for values from (false,0) to (false,1000); -create table bool_rp_true_1k partition of bool_rp for values from (true,0) to (true,1000); -create table bool_rp_false_2k partition of bool_rp for values from (false,1000) to (false,2000); -create table bool_rp_true_2k partition of bool_rp for values from (true,1000) to (true,2000); -create index on bool_rp (b,a); -explain (costs off) select * from bool_rp where b = true order by b,a; - QUERY PLAN ----------------------------------------------------------------------------------- - Append - -> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp_1 - Index Cond: (b = true) - -> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_2 - Index Cond: (b = true) -(5 rows) - -explain (costs off) select * from bool_rp where b = false order by b,a; - QUERY PLAN ------------------------------------------------------------------------------------- - Append - -> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp_1 - Index Cond: (b = false) - -> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_2 - Index Cond: (b = false) -(5 rows) - -explain (costs off) select * from bool_rp where b = true order by a; - QUERY PLAN ----------------------------------------------------------------------------------- - Append - -> Index Only Scan using bool_rp_true_1k_b_a_idx on bool_rp_true_1k bool_rp_1 - Index Cond: (b = true) - -> Index Only Scan using bool_rp_true_2k_b_a_idx on bool_rp_true_2k bool_rp_2 - Index Cond: (b = true) -(5 rows) - -explain (costs off) select * from bool_rp where b = false order by a; - QUERY PLAN ------------------------------------------------------------------------------------- - Append - -> Index Only Scan using bool_rp_false_1k_b_a_idx on bool_rp_false_1k bool_rp_1 - Index Cond: (b = false) - -> Index Only Scan using bool_rp_false_2k_b_a_idx on bool_rp_false_2k bool_rp_2 - Index Cond: (b = false) -(5 rows) - -drop table bool_rp; --- Ensure an Append scan is chosen when the partition order is a subset of --- the required order. -create table range_parted (a int, b int, c int) partition by range(a, b); -create table range_parted1 partition of range_parted for values from (0,0) to (10,10); -create table range_parted2 partition of range_parted for values from (10,10) to (20,20); -create index on range_parted (a,b,c); -explain (costs off) select * from range_parted order by a,b,c; - QUERY PLAN -------------------------------------------------------------------------------------- - Append - -> Index Only Scan using range_parted1_a_b_c_idx on range_parted1 range_parted_1 - -> Index Only Scan using range_parted2_a_b_c_idx on range_parted2 range_parted_2 -(3 rows) - -explain (costs off) select * from range_parted order by a desc,b desc,c desc; - QUERY PLAN ----------------------------------------------------------------------------------------------- - Append - -> Index Only Scan Backward using range_parted2_a_b_c_idx on range_parted2 range_parted_2 - -> Index Only Scan Backward using range_parted1_a_b_c_idx on range_parted1 range_parted_1 -(3 rows) - -drop table range_parted; --- Check that we allow access to a child table's statistics when the user --- has permissions only for the parent table. -create table permtest_parent (a int, b text, c text) partition by list (a); -create table permtest_child (b text, c text, a int) partition by list (b); -create table permtest_grandchild (c text, b text, a int); -alter table permtest_child attach partition permtest_grandchild for values in ('a'); -alter table permtest_parent attach partition permtest_child for values in (1); -create index on permtest_parent (left(c, 3)); -insert into permtest_parent - select 1, 'a', left(md5(i::text), 5) from generate_series(0, 100) i; -analyze permtest_parent; -create role regress_no_child_access; -revoke all on permtest_grandchild from regress_no_child_access; -grant select on permtest_parent to regress_no_child_access; -set session authorization regress_no_child_access; --- without stats access, these queries would produce hash join plans: -explain (costs off) - select * from permtest_parent p1 inner join permtest_parent p2 - on p1.a = p2.a and p1.c ~ 'a1$'; - QUERY PLAN ------------------------------------------- - Nested Loop - Join Filter: (p1.a = p2.a) - -> Seq Scan on permtest_grandchild p1 - Filter: (c ~ 'a1$'::text) - -> Seq Scan on permtest_grandchild p2 -(5 rows) - -explain (costs off) - select * from permtest_parent p1 inner join permtest_parent p2 - on p1.a = p2.a and left(p1.c, 3) ~ 'a1$'; - QUERY PLAN ----------------------------------------------- - Nested Loop - Join Filter: (p1.a = p2.a) - -> Seq Scan on permtest_grandchild p1 - Filter: ("left"(c, 3) ~ 'a1$'::text) - -> Seq Scan on permtest_grandchild p2 -(5 rows) - -reset session authorization; -revoke all on permtest_parent from regress_no_child_access; -grant select(a,c) on permtest_parent to regress_no_child_access; -set session authorization regress_no_child_access; -explain (costs off) - select p2.a, p1.c from permtest_parent p1 inner join permtest_parent p2 - on p1.a = p2.a and p1.c ~ 'a1$'; - QUERY PLAN ------------------------------------------- - Nested Loop - Join Filter: (p1.a = p2.a) - -> Seq Scan on permtest_grandchild p1 - Filter: (c ~ 'a1$'::text) - -> Seq Scan on permtest_grandchild p2 -(5 rows) - --- we will not have access to the expression index's stats here: -explain (costs off) - select p2.a, p1.c from permtest_parent p1 inner join permtest_parent p2 - on p1.a = p2.a and left(p1.c, 3) ~ 'a1$'; - QUERY PLAN ----------------------------------------------------- - Hash Join - Hash Cond: (p2.a = p1.a) - -> Seq Scan on permtest_grandchild p2 - -> Hash - -> Seq Scan on permtest_grandchild p1 - Filter: ("left"(c, 3) ~ 'a1$'::text) -(6 rows) - -reset session authorization; -revoke all on permtest_parent from regress_no_child_access; -drop role regress_no_child_access; -drop table permtest_parent; --- Verify that constraint errors across partition root / child are --- handled correctly (Bug #16293) -CREATE TABLE errtst_parent ( - partid int not null, - shdata int not null, - data int NOT NULL DEFAULT 0, - CONSTRAINT shdata_small CHECK(shdata < 3) -) PARTITION BY RANGE (partid); --- fast defaults lead to attribute mapping being used in one --- direction, but not the other -CREATE TABLE errtst_child_fastdef ( - partid int not null, - shdata int not null, - CONSTRAINT shdata_small CHECK(shdata < 3) -); --- no remapping in either direction necessary -CREATE TABLE errtst_child_plaindef ( - partid int not null, - shdata int not null, - data int NOT NULL DEFAULT 0, - CONSTRAINT shdata_small CHECK(shdata < 3), - CHECK(data < 10) -); --- remapping in both direction -CREATE TABLE errtst_child_reorder ( - data int NOT NULL DEFAULT 0, - shdata int not null, - partid int not null, - CONSTRAINT shdata_small CHECK(shdata < 3), - CHECK(data < 10) -); -ALTER TABLE errtst_child_fastdef ADD COLUMN data int NOT NULL DEFAULT 0; -ALTER TABLE errtst_child_fastdef ADD CONSTRAINT errtest_child_fastdef_data_check CHECK (data < 10); -ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_fastdef FOR VALUES FROM (0) TO (10); -ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_plaindef FOR VALUES FROM (10) TO (20); -ALTER TABLE errtst_parent ATTACH PARTITION errtst_child_reorder FOR VALUES FROM (20) TO (30); --- insert without child check constraint error -INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '5'); -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '5'); -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '5'); --- insert with child check constraint error -INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', '10'); -ERROR: new row for relation "errtst_child_fastdef" violates check constraint "errtest_child_fastdef_data_check" -DETAIL: Failing row contains (0, 1, 10). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', '10'); -ERROR: new row for relation "errtst_child_plaindef" violates check constraint "errtst_child_plaindef_data_check" -DETAIL: Failing row contains (10, 1, 10). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', '10'); -ERROR: new row for relation "errtst_child_reorder" violates check constraint "errtst_child_reorder_data_check" -DETAIL: Failing row contains (20, 1, 10). --- insert with child not null constraint error -INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '1', NULL); -ERROR: null value in column "data" of relation "errtst_child_fastdef" violates not-null constraint -DETAIL: Failing row contains (0, 1, null). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '1', NULL); -ERROR: null value in column "data" of relation "errtst_child_plaindef" violates not-null constraint -DETAIL: Failing row contains (10, 1, null). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '1', NULL); -ERROR: null value in column "data" of relation "errtst_child_reorder" violates not-null constraint -DETAIL: Failing row contains (20, 1, null). --- insert with shared check constraint error -INSERT INTO errtst_parent(partid, shdata, data) VALUES ( '0', '5', '5'); -ERROR: new row for relation "errtst_child_fastdef" violates check constraint "shdata_small" -DETAIL: Failing row contains (0, 5, 5). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('10', '5', '5'); -ERROR: new row for relation "errtst_child_plaindef" violates check constraint "shdata_small" -DETAIL: Failing row contains (10, 5, 5). -INSERT INTO errtst_parent(partid, shdata, data) VALUES ('20', '5', '5'); -ERROR: new row for relation "errtst_child_reorder" violates check constraint "shdata_small" -DETAIL: Failing row contains (20, 5, 5). --- within partition update without child check constraint violation -BEGIN; -UPDATE errtst_parent SET data = data + 1 WHERE partid = 0; -UPDATE errtst_parent SET data = data + 1 WHERE partid = 10; -UPDATE errtst_parent SET data = data + 1 WHERE partid = 20; -ROLLBACK; --- within partition update with child check constraint violation -UPDATE errtst_parent SET data = data + 10 WHERE partid = 0; -ERROR: new row for relation "errtst_child_fastdef" violates check constraint "errtest_child_fastdef_data_check" -DETAIL: Failing row contains (0, 1, 15). -UPDATE errtst_parent SET data = data + 10 WHERE partid = 10; -ERROR: new row for relation "errtst_child_plaindef" violates check constraint "errtst_child_plaindef_data_check" -DETAIL: Failing row contains (10, 1, 15). -UPDATE errtst_parent SET data = data + 10 WHERE partid = 20; -ERROR: new row for relation "errtst_child_reorder" violates check constraint "errtst_child_reorder_data_check" -DETAIL: Failing row contains (15, 1, 20). --- direct leaf partition update, without partition id violation -BEGIN; -UPDATE errtst_child_fastdef SET partid = 1 WHERE partid = 0; -UPDATE errtst_child_plaindef SET partid = 11 WHERE partid = 10; -UPDATE errtst_child_reorder SET partid = 21 WHERE partid = 20; -ROLLBACK; --- direct leaf partition update, with partition id violation -UPDATE errtst_child_fastdef SET partid = partid + 10 WHERE partid = 0; -ERROR: new row for relation "errtst_child_fastdef" violates partition constraint -DETAIL: Failing row contains (10, 1, 5). -UPDATE errtst_child_plaindef SET partid = partid + 10 WHERE partid = 10; -ERROR: new row for relation "errtst_child_plaindef" violates partition constraint -DETAIL: Failing row contains (20, 1, 5). -UPDATE errtst_child_reorder SET partid = partid + 10 WHERE partid = 20; -ERROR: new row for relation "errtst_child_reorder" violates partition constraint -DETAIL: Failing row contains (5, 1, 30). --- partition move, without child check constraint violation -BEGIN; -UPDATE errtst_parent SET partid = 10, data = data + 1 WHERE partid = 0; -UPDATE errtst_parent SET partid = 20, data = data + 1 WHERE partid = 10; -UPDATE errtst_parent SET partid = 0, data = data + 1 WHERE partid = 20; -ROLLBACK; --- partition move, with child check constraint violation -UPDATE errtst_parent SET partid = 10, data = data + 10 WHERE partid = 0; -ERROR: new row for relation "errtst_child_plaindef" violates check constraint "errtst_child_plaindef_data_check" -DETAIL: Failing row contains (10, 1, 15). -UPDATE errtst_parent SET partid = 20, data = data + 10 WHERE partid = 10; -ERROR: new row for relation "errtst_child_reorder" violates check constraint "errtst_child_reorder_data_check" -DETAIL: Failing row contains (20, 1, 15). -UPDATE errtst_parent SET partid = 0, data = data + 10 WHERE partid = 20; -ERROR: new row for relation "errtst_child_fastdef" violates check constraint "errtest_child_fastdef_data_check" -DETAIL: Failing row contains (0, 1, 15). --- partition move, without target partition -UPDATE errtst_parent SET partid = 30, data = data + 10 WHERE partid = 20; -ERROR: no partition of relation "errtst_parent" found for row -DETAIL: Partition key of the failing row contains (partid) = (30). -DROP TABLE errtst_parent; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/sanity_check.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/sanity_check.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/sanity_check.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/sanity_check.out 2022-02-13 01:12:12.248830843 +0100 @@ -18,7 +18,9 @@ array_op_test|f b|f b_star|f -bit_defaults|f +bit_table|f +booltbl1|f +booltbl2|f box_tbl|f bprime|f bt_f8_heap|t @@ -39,7 +41,6 @@ default_tbl|f defaultexpr_tbl|f dept|f -dupindexcols|t e_star|f emp|f equipment_r|f @@ -48,11 +49,10 @@ fast_emp4000|t float4_tbl|f float8_tbl|f -func_index_heap|t -hash_f8_heap|t -hash_i4_heap|t -hash_name_heap|t -hash_txt_heap|t +hash_f8_heap|f +hash_i4_heap|f +hash_name_heap|f +hash_txt_heap|f hobbies_r|f ihighway|t inet_tbl|f @@ -69,6 +69,10 @@ log_table|f lseg_tbl|f main_table|f +matest0|t +matest1|t +matest2|t +matest3|t mlparted|f mlparted1|f mlparted11|f @@ -194,6 +198,10 @@ tbl_include_reg|t tbl_include_unique1|t tbl_include_unique2|f +temp_float|f +temp_group|f +temp_int2|f +temp_int4|f tenk1|t tenk2|t test_range_excl|t @@ -213,6 +221,7 @@ trigger_parted_p1_1|t trigger_parted_p2|t trigger_parted_p2_2|t +varbit_table|f varchar_tbl|f view_base_table|t -- restore normal output mode diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select_distinct.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/select_distinct.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select_distinct.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/select_distinct.out 2022-02-13 01:12:12.775498398 +0100 @@ -158,151 +158,8 @@ SET jit_above_cost=0; EXPLAIN (costs off) SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; - QUERY PLAN ------------------------------------------------- - Unique - -> Sort - Sort Key: ((g % 1000)) - -> Function Scan on generate_series g -(4 rows) - -CREATE TABLE distinct_group_1 AS -SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; -SET jit_above_cost TO DEFAULT; -CREATE TABLE distinct_group_2 AS -SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g; -SET enable_hashagg=TRUE; --- Produce results with hash aggregation. -SET enable_sort=FALSE; -SET jit_above_cost=0; -EXPLAIN (costs off) -SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; - QUERY PLAN ------------------------------------------- - HashAggregate - Group Key: (g % 1000) - -> Function Scan on generate_series g -(3 rows) - -CREATE TABLE distinct_hash_1 AS -SELECT DISTINCT g%1000 FROM generate_series(0,9999) g; -SET jit_above_cost TO DEFAULT; -CREATE TABLE distinct_hash_2 AS -SELECT DISTINCT (g%1000)::text FROM generate_series(0,9999) g; -SET enable_sort=TRUE; -SET work_mem TO DEFAULT; --- Compare results -(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) - UNION ALL -(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1); - ?column? ----------- -(0 rows) - -(SELECT * FROM distinct_hash_1 EXCEPT SELECT * FROM distinct_group_1) - UNION ALL -(SELECT * FROM distinct_group_1 EXCEPT SELECT * FROM distinct_hash_1); - ?column? ----------- -(0 rows) - -DROP TABLE distinct_hash_1; -DROP TABLE distinct_hash_2; -DROP TABLE distinct_group_1; -DROP TABLE distinct_group_2; --- --- Also, some tests of IS DISTINCT FROM, which doesn't quite deserve its --- very own regression file. --- -CREATE TEMP TABLE disttable (f1 integer); -INSERT INTO DISTTABLE VALUES(1); -INSERT INTO DISTTABLE VALUES(2); -INSERT INTO DISTTABLE VALUES(3); -INSERT INTO DISTTABLE VALUES(NULL); --- basic cases -SELECT f1, f1 IS DISTINCT FROM 2 as "not 2" FROM disttable; - f1 | not 2 -----+------- - 1 | t - 2 | f - 3 | t - | t -(4 rows) - -SELECT f1, f1 IS DISTINCT FROM NULL as "not null" FROM disttable; - f1 | not null -----+---------- - 1 | t - 2 | t - 3 | t - | f -(4 rows) - -SELECT f1, f1 IS DISTINCT FROM f1 as "false" FROM disttable; - f1 | false -----+------- - 1 | f - 2 | f - 3 | f - | f -(4 rows) - -SELECT f1, f1 IS DISTINCT FROM f1+1 as "not null" FROM disttable; - f1 | not null -----+---------- - 1 | t - 2 | t - 3 | t - | f -(4 rows) - --- check that optimizer constant-folds it properly -SELECT 1 IS DISTINCT FROM 2 as "yes"; - yes ------ - t -(1 row) - -SELECT 2 IS DISTINCT FROM 2 as "no"; - no ----- - f -(1 row) - -SELECT 2 IS DISTINCT FROM null as "yes"; - yes ------ - t -(1 row) - -SELECT null IS DISTINCT FROM null as "no"; - no ----- - f -(1 row) - --- negated form -SELECT 1 IS NOT DISTINCT FROM 2 as "no"; - no ----- - f -(1 row) - -SELECT 2 IS NOT DISTINCT FROM 2 as "yes"; - yes ------ - t -(1 row) - -SELECT 2 IS NOT DISTINCT FROM null as "no"; - no ----- - f -(1 row) - -SELECT null IS NOT DISTINCT FROM null as "yes"; - yes ------ - t -(1 row) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/join.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/join.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/join.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/join.out 2022-02-13 01:12:12.848831855 +0100 @@ -663,5798 +663,8 @@ SELECT '' AS "xxx", * FROM J1_TBL CROSS JOIN J2_TBL a CROSS JOIN J2_TBL b; - xxx | i | j | t | i | k | i | k ------+---+---+-------+---+----+---+---- - | 1 | 4 | one | 1 | -1 | 1 | -1 - | 1 | 4 | one | 1 | -1 | 2 | 2 - | 1 | 4 | one | 1 | -1 | 3 | -3 - | 1 | 4 | one | 1 | -1 | 2 | 4 - | 1 | 4 | one | 1 | -1 | 5 | -5 - | 1 | 4 | one | 1 | -1 | 5 | -5 - | 1 | 4 | one | 1 | -1 | 0 | - | 1 | 4 | one | 1 | -1 | | - | 1 | 4 | one | 1 | -1 | | 0 - | 2 | 3 | two | 1 | -1 | 1 | -1 - | 2 | 3 | two | 1 | -1 | 2 | 2 - | 2 | 3 | two | 1 | -1 | 3 | -3 - | 2 | 3 | two | 1 | -1 | 2 | 4 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 5 | -5 - | 2 | 3 | two | 1 | -1 | 0 | - | 2 | 3 | two | 1 | -1 | | - | 2 | 3 | two | 1 | -1 | | 0 - | 3 | 2 | three | 1 | -1 | 1 | -1 - | 3 | 2 | three | 1 | -1 | 2 | 2 - | 3 | 2 | three | 1 | -1 | 3 | -3 - | 3 | 2 | three | 1 | -1 | 2 | 4 - | 3 | 2 | three | 1 | -1 | 5 | -5 - | 3 | 2 | three | 1 | -1 | 5 | -5 - | 3 | 2 | three | 1 | -1 | 0 | - | 3 | 2 | three | 1 | -1 | | - | 3 | 2 | three | 1 | -1 | | 0 - | 4 | 1 | four | 1 | -1 | 1 | -1 - | 4 | 1 | four | 1 | -1 | 2 | 2 - | 4 | 1 | four | 1 | -1 | 3 | -3 - | 4 | 1 | four | 1 | -1 | 2 | 4 - | 4 | 1 | four | 1 | -1 | 5 | -5 - | 4 | 1 | four | 1 | -1 | 5 | -5 - | 4 | 1 | four | 1 | -1 | 0 | - | 4 | 1 | four | 1 | -1 | | - | 4 | 1 | four | 1 | -1 | | 0 - | 5 | 0 | five | 1 | -1 | 1 | -1 - | 5 | 0 | five | 1 | -1 | 2 | 2 - | 5 | 0 | five | 1 | -1 | 3 | -3 - | 5 | 0 | five | 1 | -1 | 2 | 4 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 5 | -5 - | 5 | 0 | five | 1 | -1 | 0 | - | 5 | 0 | five | 1 | -1 | | - | 5 | 0 | five | 1 | -1 | | 0 - | 6 | 6 | six | 1 | -1 | 1 | -1 - | 6 | 6 | six | 1 | -1 | 2 | 2 - | 6 | 6 | six | 1 | -1 | 3 | -3 - | 6 | 6 | six | 1 | -1 | 2 | 4 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 5 | -5 - | 6 | 6 | six | 1 | -1 | 0 | - | 6 | 6 | six | 1 | -1 | | - | 6 | 6 | six | 1 | -1 | | 0 - | 7 | 7 | seven | 1 | -1 | 1 | -1 - | 7 | 7 | seven | 1 | -1 | 2 | 2 - | 7 | 7 | seven | 1 | -1 | 3 | -3 - | 7 | 7 | seven | 1 | -1 | 2 | 4 - | 7 | 7 | seven | 1 | -1 | 5 | -5 - | 7 | 7 | seven | 1 | -1 | 5 | -5 - | 7 | 7 | seven | 1 | -1 | 0 | - | 7 | 7 | seven | 1 | -1 | | - | 7 | 7 | seven | 1 | -1 | | 0 - | 8 | 8 | eight | 1 | -1 | 1 | -1 - | 8 | 8 | eight | 1 | -1 | 2 | 2 - | 8 | 8 | eight | 1 | -1 | 3 | -3 - | 8 | 8 | eight | 1 | -1 | 2 | 4 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 5 | -5 - | 8 | 8 | eight | 1 | -1 | 0 | - | 8 | 8 | eight | 1 | -1 | | - | 8 | 8 | eight | 1 | -1 | | 0 - | 0 | | zero | 1 | -1 | 1 | -1 - | 0 | | zero | 1 | -1 | 2 | 2 - | 0 | | zero | 1 | -1 | 3 | -3 - | 0 | | zero | 1 | -1 | 2 | 4 - | 0 | | zero | 1 | -1 | 5 | -5 - | 0 | | zero | 1 | -1 | 5 | -5 - | 0 | | zero | 1 | -1 | 0 | - | 0 | | zero | 1 | -1 | | - | 0 | | zero | 1 | -1 | | 0 - | | | null | 1 | -1 | 1 | -1 - | | | null | 1 | -1 | 2 | 2 - | | | null | 1 | -1 | 3 | -3 - | | | null | 1 | -1 | 2 | 4 - | | | null | 1 | -1 | 5 | -5 - | | | null | 1 | -1 | 5 | -5 - | | | null | 1 | -1 | 0 | - | | | null | 1 | -1 | | - | | | null | 1 | -1 | | 0 - | | 0 | zero | 1 | -1 | 1 | -1 - | | 0 | zero | 1 | -1 | 2 | 2 - | | 0 | zero | 1 | -1 | 3 | -3 - | | 0 | zero | 1 | -1 | 2 | 4 - | | 0 | zero | 1 | -1 | 5 | -5 - | | 0 | zero | 1 | -1 | 5 | -5 - | | 0 | zero | 1 | -1 | 0 | - | | 0 | zero | 1 | -1 | | - | | 0 | zero | 1 | -1 | | 0 - | 1 | 4 | one | 2 | 2 | 1 | -1 - | 1 | 4 | one | 2 | 2 | 2 | 2 - | 1 | 4 | one | 2 | 2 | 3 | -3 - | 1 | 4 | one | 2 | 2 | 2 | 4 - | 1 | 4 | one | 2 | 2 | 5 | -5 - | 1 | 4 | one | 2 | 2 | 5 | -5 - | 1 | 4 | one | 2 | 2 | 0 | - | 1 | 4 | one | 2 | 2 | | - | 1 | 4 | one | 2 | 2 | | 0 - | 2 | 3 | two | 2 | 2 | 1 | -1 - | 2 | 3 | two | 2 | 2 | 2 | 2 - | 2 | 3 | two | 2 | 2 | 3 | -3 - | 2 | 3 | two | 2 | 2 | 2 | 4 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 5 | -5 - | 2 | 3 | two | 2 | 2 | 0 | - | 2 | 3 | two | 2 | 2 | | - | 2 | 3 | two | 2 | 2 | | 0 - | 3 | 2 | three | 2 | 2 | 1 | -1 - | 3 | 2 | three | 2 | 2 | 2 | 2 - | 3 | 2 | three | 2 | 2 | 3 | -3 - | 3 | 2 | three | 2 | 2 | 2 | 4 - | 3 | 2 | three | 2 | 2 | 5 | -5 - | 3 | 2 | three | 2 | 2 | 5 | -5 - | 3 | 2 | three | 2 | 2 | 0 | - | 3 | 2 | three | 2 | 2 | | - | 3 | 2 | three | 2 | 2 | | 0 - | 4 | 1 | four | 2 | 2 | 1 | -1 - | 4 | 1 | four | 2 | 2 | 2 | 2 - | 4 | 1 | four | 2 | 2 | 3 | -3 - | 4 | 1 | four | 2 | 2 | 2 | 4 - | 4 | 1 | four | 2 | 2 | 5 | -5 - | 4 | 1 | four | 2 | 2 | 5 | -5 - | 4 | 1 | four | 2 | 2 | 0 | - | 4 | 1 | four | 2 | 2 | | - | 4 | 1 | four | 2 | 2 | | 0 - | 5 | 0 | five | 2 | 2 | 1 | -1 - | 5 | 0 | five | 2 | 2 | 2 | 2 - | 5 | 0 | five | 2 | 2 | 3 | -3 - | 5 | 0 | five | 2 | 2 | 2 | 4 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 5 | -5 - | 5 | 0 | five | 2 | 2 | 0 | - | 5 | 0 | five | 2 | 2 | | - | 5 | 0 | five | 2 | 2 | | 0 - | 6 | 6 | six | 2 | 2 | 1 | -1 - | 6 | 6 | six | 2 | 2 | 2 | 2 - | 6 | 6 | six | 2 | 2 | 3 | -3 - | 6 | 6 | six | 2 | 2 | 2 | 4 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 5 | -5 - | 6 | 6 | six | 2 | 2 | 0 | - | 6 | 6 | six | 2 | 2 | | - | 6 | 6 | six | 2 | 2 | | 0 - | 7 | 7 | seven | 2 | 2 | 1 | -1 - | 7 | 7 | seven | 2 | 2 | 2 | 2 - | 7 | 7 | seven | 2 | 2 | 3 | -3 - | 7 | 7 | seven | 2 | 2 | 2 | 4 - | 7 | 7 | seven | 2 | 2 | 5 | -5 - | 7 | 7 | seven | 2 | 2 | 5 | -5 - | 7 | 7 | seven | 2 | 2 | 0 | - | 7 | 7 | seven | 2 | 2 | | - | 7 | 7 | seven | 2 | 2 | | 0 - | 8 | 8 | eight | 2 | 2 | 1 | -1 - | 8 | 8 | eight | 2 | 2 | 2 | 2 - | 8 | 8 | eight | 2 | 2 | 3 | -3 - | 8 | 8 | eight | 2 | 2 | 2 | 4 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 5 | -5 - | 8 | 8 | eight | 2 | 2 | 0 | - | 8 | 8 | eight | 2 | 2 | | - | 8 | 8 | eight | 2 | 2 | | 0 - | 0 | | zero | 2 | 2 | 1 | -1 - | 0 | | zero | 2 | 2 | 2 | 2 - | 0 | | zero | 2 | 2 | 3 | -3 - | 0 | | zero | 2 | 2 | 2 | 4 - | 0 | | zero | 2 | 2 | 5 | -5 - | 0 | | zero | 2 | 2 | 5 | -5 - | 0 | | zero | 2 | 2 | 0 | - | 0 | | zero | 2 | 2 | | - | 0 | | zero | 2 | 2 | | 0 - | | | null | 2 | 2 | 1 | -1 - | | | null | 2 | 2 | 2 | 2 - | | | null | 2 | 2 | 3 | -3 - | | | null | 2 | 2 | 2 | 4 - | | | null | 2 | 2 | 5 | -5 - | | | null | 2 | 2 | 5 | -5 - | | | null | 2 | 2 | 0 | - | | | null | 2 | 2 | | - | | | null | 2 | 2 | | 0 - | | 0 | zero | 2 | 2 | 1 | -1 - | | 0 | zero | 2 | 2 | 2 | 2 - | | 0 | zero | 2 | 2 | 3 | -3 - | | 0 | zero | 2 | 2 | 2 | 4 - | | 0 | zero | 2 | 2 | 5 | -5 - | | 0 | zero | 2 | 2 | 5 | -5 - | | 0 | zero | 2 | 2 | 0 | - | | 0 | zero | 2 | 2 | | - | | 0 | zero | 2 | 2 | | 0 - | 1 | 4 | one | 3 | -3 | 1 | -1 - | 1 | 4 | one | 3 | -3 | 2 | 2 - | 1 | 4 | one | 3 | -3 | 3 | -3 - | 1 | 4 | one | 3 | -3 | 2 | 4 - | 1 | 4 | one | 3 | -3 | 5 | -5 - | 1 | 4 | one | 3 | -3 | 5 | -5 - | 1 | 4 | one | 3 | -3 | 0 | - | 1 | 4 | one | 3 | -3 | | - | 1 | 4 | one | 3 | -3 | | 0 - | 2 | 3 | two | 3 | -3 | 1 | -1 - | 2 | 3 | two | 3 | -3 | 2 | 2 - | 2 | 3 | two | 3 | -3 | 3 | -3 - | 2 | 3 | two | 3 | -3 | 2 | 4 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 5 | -5 - | 2 | 3 | two | 3 | -3 | 0 | - | 2 | 3 | two | 3 | -3 | | - | 2 | 3 | two | 3 | -3 | | 0 - | 3 | 2 | three | 3 | -3 | 1 | -1 - | 3 | 2 | three | 3 | -3 | 2 | 2 - | 3 | 2 | three | 3 | -3 | 3 | -3 - | 3 | 2 | three | 3 | -3 | 2 | 4 - | 3 | 2 | three | 3 | -3 | 5 | -5 - | 3 | 2 | three | 3 | -3 | 5 | -5 - | 3 | 2 | three | 3 | -3 | 0 | - | 3 | 2 | three | 3 | -3 | | - | 3 | 2 | three | 3 | -3 | | 0 - | 4 | 1 | four | 3 | -3 | 1 | -1 - | 4 | 1 | four | 3 | -3 | 2 | 2 - | 4 | 1 | four | 3 | -3 | 3 | -3 - | 4 | 1 | four | 3 | -3 | 2 | 4 - | 4 | 1 | four | 3 | -3 | 5 | -5 - | 4 | 1 | four | 3 | -3 | 5 | -5 - | 4 | 1 | four | 3 | -3 | 0 | - | 4 | 1 | four | 3 | -3 | | - | 4 | 1 | four | 3 | -3 | | 0 - | 5 | 0 | five | 3 | -3 | 1 | -1 - | 5 | 0 | five | 3 | -3 | 2 | 2 - | 5 | 0 | five | 3 | -3 | 3 | -3 - | 5 | 0 | five | 3 | -3 | 2 | 4 - | 5 | 0 | five | 3 | -3 | 5 | -5 - | 5 | 0 | five | 3 | -3 | 5 | -5 - | 5 | 0 | five | 3 | -3 | 0 | - | 5 | 0 | five | 3 | -3 | | - | 5 | 0 | five | 3 | -3 | | 0 - | 6 | 6 | six | 3 | -3 | 1 | -1 - | 6 | 6 | six | 3 | -3 | 2 | 2 - | 6 | 6 | six | 3 | -3 | 3 | -3 - | 6 | 6 | six | 3 | -3 | 2 | 4 - | 6 | 6 | six | 3 | -3 | 5 | -5 - | 6 | 6 | six | 3 | -3 | 5 | -5 - | 6 | 6 | six | 3 | -3 | 0 | - | 6 | 6 | six | 3 | -3 | | - | 6 | 6 | six | 3 | -3 | | 0 - | 7 | 7 | seven | 3 | -3 | 1 | -1 - | 7 | 7 | seven | 3 | -3 | 2 | 2 - | 7 | 7 | seven | 3 | -3 | 3 | -3 - | 7 | 7 | seven | 3 | -3 | 2 | 4 - | 7 | 7 | seven | 3 | -3 | 5 | -5 - | 7 | 7 | seven | 3 | -3 | 5 | -5 - | 7 | 7 | seven | 3 | -3 | 0 | - | 7 | 7 | seven | 3 | -3 | | - | 7 | 7 | seven | 3 | -3 | | 0 - | 8 | 8 | eight | 3 | -3 | 1 | -1 - | 8 | 8 | eight | 3 | -3 | 2 | 2 - | 8 | 8 | eight | 3 | -3 | 3 | -3 - | 8 | 8 | eight | 3 | -3 | 2 | 4 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 5 | -5 - | 8 | 8 | eight | 3 | -3 | 0 | - | 8 | 8 | eight | 3 | -3 | | - | 8 | 8 | eight | 3 | -3 | | 0 - | 0 | | zero | 3 | -3 | 1 | -1 - | 0 | | zero | 3 | -3 | 2 | 2 - | 0 | | zero | 3 | -3 | 3 | -3 - | 0 | | zero | 3 | -3 | 2 | 4 - | 0 | | zero | 3 | -3 | 5 | -5 - | 0 | | zero | 3 | -3 | 5 | -5 - | 0 | | zero | 3 | -3 | 0 | - | 0 | | zero | 3 | -3 | | - | 0 | | zero | 3 | -3 | | 0 - | | | null | 3 | -3 | 1 | -1 - | | | null | 3 | -3 | 2 | 2 - | | | null | 3 | -3 | 3 | -3 - | | | null | 3 | -3 | 2 | 4 - | | | null | 3 | -3 | 5 | -5 - | | | null | 3 | -3 | 5 | -5 - | | | null | 3 | -3 | 0 | - | | | null | 3 | -3 | | - | | | null | 3 | -3 | | 0 - | | 0 | zero | 3 | -3 | 1 | -1 - | | 0 | zero | 3 | -3 | 2 | 2 - | | 0 | zero | 3 | -3 | 3 | -3 - | | 0 | zero | 3 | -3 | 2 | 4 - | | 0 | zero | 3 | -3 | 5 | -5 - | | 0 | zero | 3 | -3 | 5 | -5 - | | 0 | zero | 3 | -3 | 0 | - | | 0 | zero | 3 | -3 | | - | | 0 | zero | 3 | -3 | | 0 - | 1 | 4 | one | 2 | 4 | 1 | -1 - | 1 | 4 | one | 2 | 4 | 2 | 2 - | 1 | 4 | one | 2 | 4 | 3 | -3 - | 1 | 4 | one | 2 | 4 | 2 | 4 - | 1 | 4 | one | 2 | 4 | 5 | -5 - | 1 | 4 | one | 2 | 4 | 5 | -5 - | 1 | 4 | one | 2 | 4 | 0 | - | 1 | 4 | one | 2 | 4 | | - | 1 | 4 | one | 2 | 4 | | 0 - | 2 | 3 | two | 2 | 4 | 1 | -1 - | 2 | 3 | two | 2 | 4 | 2 | 2 - | 2 | 3 | two | 2 | 4 | 3 | -3 - | 2 | 3 | two | 2 | 4 | 2 | 4 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 5 | -5 - | 2 | 3 | two | 2 | 4 | 0 | - | 2 | 3 | two | 2 | 4 | | - | 2 | 3 | two | 2 | 4 | | 0 - | 3 | 2 | three | 2 | 4 | 1 | -1 - | 3 | 2 | three | 2 | 4 | 2 | 2 - | 3 | 2 | three | 2 | 4 | 3 | -3 - | 3 | 2 | three | 2 | 4 | 2 | 4 - | 3 | 2 | three | 2 | 4 | 5 | -5 - | 3 | 2 | three | 2 | 4 | 5 | -5 - | 3 | 2 | three | 2 | 4 | 0 | - | 3 | 2 | three | 2 | 4 | | - | 3 | 2 | three | 2 | 4 | | 0 - | 4 | 1 | four | 2 | 4 | 1 | -1 - | 4 | 1 | four | 2 | 4 | 2 | 2 - | 4 | 1 | four | 2 | 4 | 3 | -3 - | 4 | 1 | four | 2 | 4 | 2 | 4 - | 4 | 1 | four | 2 | 4 | 5 | -5 - | 4 | 1 | four | 2 | 4 | 5 | -5 - | 4 | 1 | four | 2 | 4 | 0 | - | 4 | 1 | four | 2 | 4 | | - | 4 | 1 | four | 2 | 4 | | 0 - | 5 | 0 | five | 2 | 4 | 1 | -1 - | 5 | 0 | five | 2 | 4 | 2 | 2 - | 5 | 0 | five | 2 | 4 | 3 | -3 - | 5 | 0 | five | 2 | 4 | 2 | 4 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 5 | -5 - | 5 | 0 | five | 2 | 4 | 0 | - | 5 | 0 | five | 2 | 4 | | - | 5 | 0 | five | 2 | 4 | | 0 - | 6 | 6 | six | 2 | 4 | 1 | -1 - | 6 | 6 | six | 2 | 4 | 2 | 2 - | 6 | 6 | six | 2 | 4 | 3 | -3 - | 6 | 6 | six | 2 | 4 | 2 | 4 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 5 | -5 - | 6 | 6 | six | 2 | 4 | 0 | - | 6 | 6 | six | 2 | 4 | | - | 6 | 6 | six | 2 | 4 | | 0 - | 7 | 7 | seven | 2 | 4 | 1 | -1 - | 7 | 7 | seven | 2 | 4 | 2 | 2 - | 7 | 7 | seven | 2 | 4 | 3 | -3 - | 7 | 7 | seven | 2 | 4 | 2 | 4 - | 7 | 7 | seven | 2 | 4 | 5 | -5 - | 7 | 7 | seven | 2 | 4 | 5 | -5 - | 7 | 7 | seven | 2 | 4 | 0 | - | 7 | 7 | seven | 2 | 4 | | - | 7 | 7 | seven | 2 | 4 | | 0 - | 8 | 8 | eight | 2 | 4 | 1 | -1 - | 8 | 8 | eight | 2 | 4 | 2 | 2 - | 8 | 8 | eight | 2 | 4 | 3 | -3 - | 8 | 8 | eight | 2 | 4 | 2 | 4 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 5 | -5 - | 8 | 8 | eight | 2 | 4 | 0 | - | 8 | 8 | eight | 2 | 4 | | - | 8 | 8 | eight | 2 | 4 | | 0 - | 0 | | zero | 2 | 4 | 1 | -1 - | 0 | | zero | 2 | 4 | 2 | 2 - | 0 | | zero | 2 | 4 | 3 | -3 - | 0 | | zero | 2 | 4 | 2 | 4 - | 0 | | zero | 2 | 4 | 5 | -5 - | 0 | | zero | 2 | 4 | 5 | -5 - | 0 | | zero | 2 | 4 | 0 | - | 0 | | zero | 2 | 4 | | - | 0 | | zero | 2 | 4 | | 0 - | | | null | 2 | 4 | 1 | -1 - | | | null | 2 | 4 | 2 | 2 - | | | null | 2 | 4 | 3 | -3 - | | | null | 2 | 4 | 2 | 4 - | | | null | 2 | 4 | 5 | -5 - | | | null | 2 | 4 | 5 | -5 - | | | null | 2 | 4 | 0 | - | | | null | 2 | 4 | | - | | | null | 2 | 4 | | 0 - | | 0 | zero | 2 | 4 | 1 | -1 - | | 0 | zero | 2 | 4 | 2 | 2 - | | 0 | zero | 2 | 4 | 3 | -3 - | | 0 | zero | 2 | 4 | 2 | 4 - | | 0 | zero | 2 | 4 | 5 | -5 - | | 0 | zero | 2 | 4 | 5 | -5 - | | 0 | zero | 2 | 4 | 0 | - | | 0 | zero | 2 | 4 | | - | | 0 | zero | 2 | 4 | | 0 - | 1 | 4 | one | 5 | -5 | 1 | -1 - | 1 | 4 | one | 5 | -5 | 2 | 2 - | 1 | 4 | one | 5 | -5 | 3 | -3 - | 1 | 4 | one | 5 | -5 | 2 | 4 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 0 | - | 1 | 4 | one | 5 | -5 | | - | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 - | 3 | 2 | three | 5 | -5 | 1 | -1 - | 3 | 2 | three | 5 | -5 | 2 | 2 - | 3 | 2 | three | 5 | -5 | 3 | -3 - | 3 | 2 | three | 5 | -5 | 2 | 4 - | 3 | 2 | three | 5 | -5 | 5 | -5 - | 3 | 2 | three | 5 | -5 | 5 | -5 - | 3 | 2 | three | 5 | -5 | 0 | - | 3 | 2 | three | 5 | -5 | | - | 3 | 2 | three | 5 | -5 | | 0 - | 4 | 1 | four | 5 | -5 | 1 | -1 - | 4 | 1 | four | 5 | -5 | 2 | 2 - | 4 | 1 | four | 5 | -5 | 3 | -3 - | 4 | 1 | four | 5 | -5 | 2 | 4 - | 4 | 1 | four | 5 | -5 | 5 | -5 - | 4 | 1 | four | 5 | -5 | 5 | -5 - | 4 | 1 | four | 5 | -5 | 0 | - | 4 | 1 | four | 5 | -5 | | - | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 - | 7 | 7 | seven | 5 | -5 | 1 | -1 - | 7 | 7 | seven | 5 | -5 | 2 | 2 - | 7 | 7 | seven | 5 | -5 | 3 | -3 - | 7 | 7 | seven | 5 | -5 | 2 | 4 - | 7 | 7 | seven | 5 | -5 | 5 | -5 - | 7 | 7 | seven | 5 | -5 | 5 | -5 - | 7 | 7 | seven | 5 | -5 | 0 | - | 7 | 7 | seven | 5 | -5 | | - | 7 | 7 | seven | 5 | -5 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 0 | | zero | 5 | -5 | 1 | -1 - | 0 | | zero | 5 | -5 | 2 | 2 - | 0 | | zero | 5 | -5 | 3 | -3 - | 0 | | zero | 5 | -5 | 2 | 4 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 0 | - | 0 | | zero | 5 | -5 | | - | 0 | | zero | 5 | -5 | | 0 - | | | null | 5 | -5 | 1 | -1 - | | | null | 5 | -5 | 2 | 2 - | | | null | 5 | -5 | 3 | -3 - | | | null | 5 | -5 | 2 | 4 - | | | null | 5 | -5 | 5 | -5 - | | | null | 5 | -5 | 5 | -5 - | | | null | 5 | -5 | 0 | - | | | null | 5 | -5 | | - | | | null | 5 | -5 | | 0 - | | 0 | zero | 5 | -5 | 1 | -1 - | | 0 | zero | 5 | -5 | 2 | 2 - | | 0 | zero | 5 | -5 | 3 | -3 - | | 0 | zero | 5 | -5 | 2 | 4 - | | 0 | zero | 5 | -5 | 5 | -5 - | | 0 | zero | 5 | -5 | 5 | -5 - | | 0 | zero | 5 | -5 | 0 | - | | 0 | zero | 5 | -5 | | - | | 0 | zero | 5 | -5 | | 0 - | 1 | 4 | one | 5 | -5 | 1 | -1 - | 1 | 4 | one | 5 | -5 | 2 | 2 - | 1 | 4 | one | 5 | -5 | 3 | -3 - | 1 | 4 | one | 5 | -5 | 2 | 4 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 5 | -5 - | 1 | 4 | one | 5 | -5 | 0 | - | 1 | 4 | one | 5 | -5 | | - | 1 | 4 | one | 5 | -5 | | 0 - | 2 | 3 | two | 5 | -5 | 1 | -1 - | 2 | 3 | two | 5 | -5 | 2 | 2 - | 2 | 3 | two | 5 | -5 | 3 | -3 - | 2 | 3 | two | 5 | -5 | 2 | 4 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 5 | -5 - | 2 | 3 | two | 5 | -5 | 0 | - | 2 | 3 | two | 5 | -5 | | - | 2 | 3 | two | 5 | -5 | | 0 - | 3 | 2 | three | 5 | -5 | 1 | -1 - | 3 | 2 | three | 5 | -5 | 2 | 2 - | 3 | 2 | three | 5 | -5 | 3 | -3 - | 3 | 2 | three | 5 | -5 | 2 | 4 - | 3 | 2 | three | 5 | -5 | 5 | -5 - | 3 | 2 | three | 5 | -5 | 5 | -5 - | 3 | 2 | three | 5 | -5 | 0 | - | 3 | 2 | three | 5 | -5 | | - | 3 | 2 | three | 5 | -5 | | 0 - | 4 | 1 | four | 5 | -5 | 1 | -1 - | 4 | 1 | four | 5 | -5 | 2 | 2 - | 4 | 1 | four | 5 | -5 | 3 | -3 - | 4 | 1 | four | 5 | -5 | 2 | 4 - | 4 | 1 | four | 5 | -5 | 5 | -5 - | 4 | 1 | four | 5 | -5 | 5 | -5 - | 4 | 1 | four | 5 | -5 | 0 | - | 4 | 1 | four | 5 | -5 | | - | 4 | 1 | four | 5 | -5 | | 0 - | 5 | 0 | five | 5 | -5 | 1 | -1 - | 5 | 0 | five | 5 | -5 | 2 | 2 - | 5 | 0 | five | 5 | -5 | 3 | -3 - | 5 | 0 | five | 5 | -5 | 2 | 4 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 5 | -5 - | 5 | 0 | five | 5 | -5 | 0 | - | 5 | 0 | five | 5 | -5 | | - | 5 | 0 | five | 5 | -5 | | 0 - | 6 | 6 | six | 5 | -5 | 1 | -1 - | 6 | 6 | six | 5 | -5 | 2 | 2 - | 6 | 6 | six | 5 | -5 | 3 | -3 - | 6 | 6 | six | 5 | -5 | 2 | 4 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 5 | -5 - | 6 | 6 | six | 5 | -5 | 0 | - | 6 | 6 | six | 5 | -5 | | - | 6 | 6 | six | 5 | -5 | | 0 - | 7 | 7 | seven | 5 | -5 | 1 | -1 - | 7 | 7 | seven | 5 | -5 | 2 | 2 - | 7 | 7 | seven | 5 | -5 | 3 | -3 - | 7 | 7 | seven | 5 | -5 | 2 | 4 - | 7 | 7 | seven | 5 | -5 | 5 | -5 - | 7 | 7 | seven | 5 | -5 | 5 | -5 - | 7 | 7 | seven | 5 | -5 | 0 | - | 7 | 7 | seven | 5 | -5 | | - | 7 | 7 | seven | 5 | -5 | | 0 - | 8 | 8 | eight | 5 | -5 | 1 | -1 - | 8 | 8 | eight | 5 | -5 | 2 | 2 - | 8 | 8 | eight | 5 | -5 | 3 | -3 - | 8 | 8 | eight | 5 | -5 | 2 | 4 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 5 | -5 - | 8 | 8 | eight | 5 | -5 | 0 | - | 8 | 8 | eight | 5 | -5 | | - | 8 | 8 | eight | 5 | -5 | | 0 - | 0 | | zero | 5 | -5 | 1 | -1 - | 0 | | zero | 5 | -5 | 2 | 2 - | 0 | | zero | 5 | -5 | 3 | -3 - | 0 | | zero | 5 | -5 | 2 | 4 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 5 | -5 - | 0 | | zero | 5 | -5 | 0 | - | 0 | | zero | 5 | -5 | | - | 0 | | zero | 5 | -5 | | 0 - | | | null | 5 | -5 | 1 | -1 - | | | null | 5 | -5 | 2 | 2 - | | | null | 5 | -5 | 3 | -3 - | | | null | 5 | -5 | 2 | 4 - | | | null | 5 | -5 | 5 | -5 - | | | null | 5 | -5 | 5 | -5 - | | | null | 5 | -5 | 0 | - | | | null | 5 | -5 | | - | | | null | 5 | -5 | | 0 - | | 0 | zero | 5 | -5 | 1 | -1 - | | 0 | zero | 5 | -5 | 2 | 2 - | | 0 | zero | 5 | -5 | 3 | -3 - | | 0 | zero | 5 | -5 | 2 | 4 - | | 0 | zero | 5 | -5 | 5 | -5 - | | 0 | zero | 5 | -5 | 5 | -5 - | | 0 | zero | 5 | -5 | 0 | - | | 0 | zero | 5 | -5 | | - | | 0 | zero | 5 | -5 | | 0 - | 1 | 4 | one | 0 | | 1 | -1 - | 1 | 4 | one | 0 | | 2 | 2 - | 1 | 4 | one | 0 | | 3 | -3 - | 1 | 4 | one | 0 | | 2 | 4 - | 1 | 4 | one | 0 | | 5 | -5 - | 1 | 4 | one | 0 | | 5 | -5 - | 1 | 4 | one | 0 | | 0 | - | 1 | 4 | one | 0 | | | - | 1 | 4 | one | 0 | | | 0 - | 2 | 3 | two | 0 | | 1 | -1 - | 2 | 3 | two | 0 | | 2 | 2 - | 2 | 3 | two | 0 | | 3 | -3 - | 2 | 3 | two | 0 | | 2 | 4 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 5 | -5 - | 2 | 3 | two | 0 | | 0 | - | 2 | 3 | two | 0 | | | - | 2 | 3 | two | 0 | | | 0 - | 3 | 2 | three | 0 | | 1 | -1 - | 3 | 2 | three | 0 | | 2 | 2 - | 3 | 2 | three | 0 | | 3 | -3 - | 3 | 2 | three | 0 | | 2 | 4 - | 3 | 2 | three | 0 | | 5 | -5 - | 3 | 2 | three | 0 | | 5 | -5 - | 3 | 2 | three | 0 | | 0 | - | 3 | 2 | three | 0 | | | - | 3 | 2 | three | 0 | | | 0 - | 4 | 1 | four | 0 | | 1 | -1 - | 4 | 1 | four | 0 | | 2 | 2 - | 4 | 1 | four | 0 | | 3 | -3 - | 4 | 1 | four | 0 | | 2 | 4 - | 4 | 1 | four | 0 | | 5 | -5 - | 4 | 1 | four | 0 | | 5 | -5 - | 4 | 1 | four | 0 | | 0 | - | 4 | 1 | four | 0 | | | - | 4 | 1 | four | 0 | | | 0 - | 5 | 0 | five | 0 | | 1 | -1 - | 5 | 0 | five | 0 | | 2 | 2 - | 5 | 0 | five | 0 | | 3 | -3 - | 5 | 0 | five | 0 | | 2 | 4 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 5 | -5 - | 5 | 0 | five | 0 | | 0 | - | 5 | 0 | five | 0 | | | - | 5 | 0 | five | 0 | | | 0 - | 6 | 6 | six | 0 | | 1 | -1 - | 6 | 6 | six | 0 | | 2 | 2 - | 6 | 6 | six | 0 | | 3 | -3 - | 6 | 6 | six | 0 | | 2 | 4 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 5 | -5 - | 6 | 6 | six | 0 | | 0 | - | 6 | 6 | six | 0 | | | - | 6 | 6 | six | 0 | | | 0 - | 7 | 7 | seven | 0 | | 1 | -1 - | 7 | 7 | seven | 0 | | 2 | 2 - | 7 | 7 | seven | 0 | | 3 | -3 - | 7 | 7 | seven | 0 | | 2 | 4 - | 7 | 7 | seven | 0 | | 5 | -5 - | 7 | 7 | seven | 0 | | 5 | -5 - | 7 | 7 | seven | 0 | | 0 | - | 7 | 7 | seven | 0 | | | - | 7 | 7 | seven | 0 | | | 0 - | 8 | 8 | eight | 0 | | 1 | -1 - | 8 | 8 | eight | 0 | | 2 | 2 - | 8 | 8 | eight | 0 | | 3 | -3 - | 8 | 8 | eight | 0 | | 2 | 4 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 5 | -5 - | 8 | 8 | eight | 0 | | 0 | - | 8 | 8 | eight | 0 | | | - | 8 | 8 | eight | 0 | | | 0 - | 0 | | zero | 0 | | 1 | -1 - | 0 | | zero | 0 | | 2 | 2 - | 0 | | zero | 0 | | 3 | -3 - | 0 | | zero | 0 | | 2 | 4 - | 0 | | zero | 0 | | 5 | -5 - | 0 | | zero | 0 | | 5 | -5 - | 0 | | zero | 0 | | 0 | - | 0 | | zero | 0 | | | - | 0 | | zero | 0 | | | 0 - | | | null | 0 | | 1 | -1 - | | | null | 0 | | 2 | 2 - | | | null | 0 | | 3 | -3 - | | | null | 0 | | 2 | 4 - | | | null | 0 | | 5 | -5 - | | | null | 0 | | 5 | -5 - | | | null | 0 | | 0 | - | | | null | 0 | | | - | | | null | 0 | | | 0 - | | 0 | zero | 0 | | 1 | -1 - | | 0 | zero | 0 | | 2 | 2 - | | 0 | zero | 0 | | 3 | -3 - | | 0 | zero | 0 | | 2 | 4 - | | 0 | zero | 0 | | 5 | -5 - | | 0 | zero | 0 | | 5 | -5 - | | 0 | zero | 0 | | 0 | - | | 0 | zero | 0 | | | - | | 0 | zero | 0 | | | 0 - | 1 | 4 | one | | | 1 | -1 - | 1 | 4 | one | | | 2 | 2 - | 1 | 4 | one | | | 3 | -3 - | 1 | 4 | one | | | 2 | 4 - | 1 | 4 | one | | | 5 | -5 - | 1 | 4 | one | | | 5 | -5 - | 1 | 4 | one | | | 0 | - | 1 | 4 | one | | | | - | 1 | 4 | one | | | | 0 - | 2 | 3 | two | | | 1 | -1 - | 2 | 3 | two | | | 2 | 2 - | 2 | 3 | two | | | 3 | -3 - | 2 | 3 | two | | | 2 | 4 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 5 | -5 - | 2 | 3 | two | | | 0 | - | 2 | 3 | two | | | | - | 2 | 3 | two | | | | 0 - | 3 | 2 | three | | | 1 | -1 - | 3 | 2 | three | | | 2 | 2 - | 3 | 2 | three | | | 3 | -3 - | 3 | 2 | three | | | 2 | 4 - | 3 | 2 | three | | | 5 | -5 - | 3 | 2 | three | | | 5 | -5 - | 3 | 2 | three | | | 0 | - | 3 | 2 | three | | | | - | 3 | 2 | three | | | | 0 - | 4 | 1 | four | | | 1 | -1 - | 4 | 1 | four | | | 2 | 2 - | 4 | 1 | four | | | 3 | -3 - | 4 | 1 | four | | | 2 | 4 - | 4 | 1 | four | | | 5 | -5 - | 4 | 1 | four | | | 5 | -5 - | 4 | 1 | four | | | 0 | - | 4 | 1 | four | | | | - | 4 | 1 | four | | | | 0 - | 5 | 0 | five | | | 1 | -1 - | 5 | 0 | five | | | 2 | 2 - | 5 | 0 | five | | | 3 | -3 - | 5 | 0 | five | | | 2 | 4 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 5 | -5 - | 5 | 0 | five | | | 0 | - | 5 | 0 | five | | | | - | 5 | 0 | five | | | | 0 - | 6 | 6 | six | | | 1 | -1 - | 6 | 6 | six | | | 2 | 2 - | 6 | 6 | six | | | 3 | -3 - | 6 | 6 | six | | | 2 | 4 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 5 | -5 - | 6 | 6 | six | | | 0 | - | 6 | 6 | six | | | | - | 6 | 6 | six | | | | 0 - | 7 | 7 | seven | | | 1 | -1 - | 7 | 7 | seven | | | 2 | 2 - | 7 | 7 | seven | | | 3 | -3 - | 7 | 7 | seven | | | 2 | 4 - | 7 | 7 | seven | | | 5 | -5 - | 7 | 7 | seven | | | 5 | -5 - | 7 | 7 | seven | | | 0 | - | 7 | 7 | seven | | | | - | 7 | 7 | seven | | | | 0 - | 8 | 8 | eight | | | 1 | -1 - | 8 | 8 | eight | | | 2 | 2 - | 8 | 8 | eight | | | 3 | -3 - | 8 | 8 | eight | | | 2 | 4 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 5 | -5 - | 8 | 8 | eight | | | 0 | - | 8 | 8 | eight | | | | - | 8 | 8 | eight | | | | 0 - | 0 | | zero | | | 1 | -1 - | 0 | | zero | | | 2 | 2 - | 0 | | zero | | | 3 | -3 - | 0 | | zero | | | 2 | 4 - | 0 | | zero | | | 5 | -5 - | 0 | | zero | | | 5 | -5 - | 0 | | zero | | | 0 | - | 0 | | zero | | | | - | 0 | | zero | | | | 0 - | | | null | | | 1 | -1 - | | | null | | | 2 | 2 - | | | null | | | 3 | -3 - | | | null | | | 2 | 4 - | | | null | | | 5 | -5 - | | | null | | | 5 | -5 - | | | null | | | 0 | - | | | null | | | | - | | | null | | | | 0 - | | 0 | zero | | | 1 | -1 - | | 0 | zero | | | 2 | 2 - | | 0 | zero | | | 3 | -3 - | | 0 | zero | | | 2 | 4 - | | 0 | zero | | | 5 | -5 - | | 0 | zero | | | 5 | -5 - | | 0 | zero | | | 0 | - | | 0 | zero | | | | - | | 0 | zero | | | | 0 - | 1 | 4 | one | | 0 | 1 | -1 - | 1 | 4 | one | | 0 | 2 | 2 - | 1 | 4 | one | | 0 | 3 | -3 - | 1 | 4 | one | | 0 | 2 | 4 - | 1 | 4 | one | | 0 | 5 | -5 - | 1 | 4 | one | | 0 | 5 | -5 - | 1 | 4 | one | | 0 | 0 | - | 1 | 4 | one | | 0 | | - | 1 | 4 | one | | 0 | | 0 - | 2 | 3 | two | | 0 | 1 | -1 - | 2 | 3 | two | | 0 | 2 | 2 - | 2 | 3 | two | | 0 | 3 | -3 - | 2 | 3 | two | | 0 | 2 | 4 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 5 | -5 - | 2 | 3 | two | | 0 | 0 | - | 2 | 3 | two | | 0 | | - | 2 | 3 | two | | 0 | | 0 - | 3 | 2 | three | | 0 | 1 | -1 - | 3 | 2 | three | | 0 | 2 | 2 - | 3 | 2 | three | | 0 | 3 | -3 - | 3 | 2 | three | | 0 | 2 | 4 - | 3 | 2 | three | | 0 | 5 | -5 - | 3 | 2 | three | | 0 | 5 | -5 - | 3 | 2 | three | | 0 | 0 | - | 3 | 2 | three | | 0 | | - | 3 | 2 | three | | 0 | | 0 - | 4 | 1 | four | | 0 | 1 | -1 - | 4 | 1 | four | | 0 | 2 | 2 - | 4 | 1 | four | | 0 | 3 | -3 - | 4 | 1 | four | | 0 | 2 | 4 - | 4 | 1 | four | | 0 | 5 | -5 - | 4 | 1 | four | | 0 | 5 | -5 - | 4 | 1 | four | | 0 | 0 | - | 4 | 1 | four | | 0 | | - | 4 | 1 | four | | 0 | | 0 - | 5 | 0 | five | | 0 | 1 | -1 - | 5 | 0 | five | | 0 | 2 | 2 - | 5 | 0 | five | | 0 | 3 | -3 - | 5 | 0 | five | | 0 | 2 | 4 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 5 | -5 - | 5 | 0 | five | | 0 | 0 | - | 5 | 0 | five | | 0 | | - | 5 | 0 | five | | 0 | | 0 - | 6 | 6 | six | | 0 | 1 | -1 - | 6 | 6 | six | | 0 | 2 | 2 - | 6 | 6 | six | | 0 | 3 | -3 - | 6 | 6 | six | | 0 | 2 | 4 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 5 | -5 - | 6 | 6 | six | | 0 | 0 | - | 6 | 6 | six | | 0 | | - | 6 | 6 | six | | 0 | | 0 - | 7 | 7 | seven | | 0 | 1 | -1 - | 7 | 7 | seven | | 0 | 2 | 2 - | 7 | 7 | seven | | 0 | 3 | -3 - | 7 | 7 | seven | | 0 | 2 | 4 - | 7 | 7 | seven | | 0 | 5 | -5 - | 7 | 7 | seven | | 0 | 5 | -5 - | 7 | 7 | seven | | 0 | 0 | - | 7 | 7 | seven | | 0 | | - | 7 | 7 | seven | | 0 | | 0 - | 8 | 8 | eight | | 0 | 1 | -1 - | 8 | 8 | eight | | 0 | 2 | 2 - | 8 | 8 | eight | | 0 | 3 | -3 - | 8 | 8 | eight | | 0 | 2 | 4 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 5 | -5 - | 8 | 8 | eight | | 0 | 0 | - | 8 | 8 | eight | | 0 | | - | 8 | 8 | eight | | 0 | | 0 - | 0 | | zero | | 0 | 1 | -1 - | 0 | | zero | | 0 | 2 | 2 - | 0 | | zero | | 0 | 3 | -3 - | 0 | | zero | | 0 | 2 | 4 - | 0 | | zero | | 0 | 5 | -5 - | 0 | | zero | | 0 | 5 | -5 - | 0 | | zero | | 0 | 0 | - | 0 | | zero | | 0 | | - | 0 | | zero | | 0 | | 0 - | | | null | | 0 | 1 | -1 - | | | null | | 0 | 2 | 2 - | | | null | | 0 | 3 | -3 - | | | null | | 0 | 2 | 4 - | | | null | | 0 | 5 | -5 - | | | null | | 0 | 5 | -5 - | | | null | | 0 | 0 | - | | | null | | 0 | | - | | | null | | 0 | | 0 - | | 0 | zero | | 0 | 1 | -1 - | | 0 | zero | | 0 | 2 | 2 - | | 0 | zero | | 0 | 3 | -3 - | | 0 | zero | | 0 | 2 | 4 - | | 0 | zero | | 0 | 5 | -5 - | | 0 | zero | | 0 | 5 | -5 - | | 0 | zero | | 0 | 0 | - | | 0 | zero | | 0 | | - | | 0 | zero | | 0 | | 0 -(891 rows) - --- --- --- Inner joins (equi-joins) --- --- --- --- Inner joins (equi-joins) with USING clause --- The USING syntax changes the shape of the resulting table --- by including a column in the USING clause only once in the result. --- --- Inner equi-join on specified column -SELECT '' AS "xxx", * - FROM J1_TBL INNER JOIN J2_TBL USING (i); - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - --- Same as above, slightly different syntax -SELECT '' AS "xxx", * - FROM J1_TBL JOIN J2_TBL USING (i); - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, d) USING (a) - ORDER BY a, d; - xxx | a | b | c | d ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) - ORDER BY b, t1.a; - xxx | b | a | c | a ------+---+---+-------+--- - | 0 | 5 | five | - | 0 | | zero | - | 2 | 3 | three | 2 - | 4 | 1 | one | 2 -(4 rows) - --- --- NATURAL JOIN --- Inner equi-join on all columns with the same name --- -SELECT '' AS "xxx", * - FROM J1_TBL NATURAL JOIN J2_TBL; - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); - xxx | a | b | c | d ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); - xxx | a | b | c | d ------+---+---+------+--- - | 0 | | zero | - | 2 | 3 | two | 2 - | 4 | 1 | four | 2 -(3 rows) - --- mismatch number of columns --- currently, Postgres will fill in with underlying names -SELECT '' AS "xxx", * - FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); - xxx | a | b | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 -(7 rows) - --- --- Inner joins (equi-joins) --- -SELECT '' AS "xxx", * - FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); - xxx | i | j | t | i | k ------+---+---+-------+---+---- - | 0 | | zero | 0 | - | 1 | 4 | one | 1 | -1 - | 2 | 3 | two | 2 | 2 - | 2 | 3 | two | 2 | 4 - | 3 | 2 | three | 3 | -3 - | 5 | 0 | five | 5 | -5 - | 5 | 0 | five | 5 | -5 -(7 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); - xxx | i | j | t | i | k ------+---+---+------+---+--- - | 0 | | zero | | 0 - | 2 | 3 | two | 2 | 2 - | 4 | 1 | four | 2 | 4 -(3 rows) - --- --- Non-equi-joins --- -SELECT '' AS "xxx", * - FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); - xxx | i | j | t | i | k ------+---+---+-------+---+--- - | 1 | 4 | one | 2 | 2 - | 2 | 3 | two | 2 | 2 - | 0 | | zero | 2 | 2 - | 1 | 4 | one | 2 | 4 - | 2 | 3 | two | 2 | 4 - | 3 | 2 | three | 2 | 4 - | 4 | 1 | four | 2 | 4 - | 0 | | zero | 2 | 4 - | 0 | | zero | | 0 -(9 rows) - --- --- Outer joins --- Note that OUTER is a noise word --- -SELECT '' AS "xxx", * - FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) - ORDER BY i, k, t; - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 4 | 1 | four | - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 6 | 6 | six | - | 7 | 7 | seven | - | 8 | 8 | eight | - | | | null | - | | 0 | zero | -(13 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL LEFT JOIN J2_TBL USING (i) - ORDER BY i, k, t; - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 4 | 1 | four | - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 6 | 6 | six | - | 7 | 7 | seven | - | 8 | 8 | eight | - | | | null | - | | 0 | zero | -(13 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | | | | - | | | | 0 -(9 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL RIGHT JOIN J2_TBL USING (i); - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | | | | - | | | | 0 -(9 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) - ORDER BY i, k, t; - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 4 | 1 | four | - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 6 | 6 | six | - | 7 | 7 | seven | - | 8 | 8 | eight | - | | | | 0 - | | | null | - | | 0 | zero | - | | | | -(15 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL FULL JOIN J2_TBL USING (i) - ORDER BY i, k, t; - xxx | i | j | t | k ------+---+---+-------+---- - | 0 | | zero | - | 1 | 4 | one | -1 - | 2 | 3 | two | 2 - | 2 | 3 | two | 4 - | 3 | 2 | three | -3 - | 4 | 1 | four | - | 5 | 0 | five | -5 - | 5 | 0 | five | -5 - | 6 | 6 | six | - | 7 | 7 | seven | - | 8 | 8 | eight | - | | | | 0 - | | | null | - | | 0 | zero | - | | | | -(15 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); - xxx | i | j | t | k ------+---+---+---+--- -(0 rows) - -SELECT '' AS "xxx", * - FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); - xxx | i | j | t | k ------+---+---+-----+---- - | 1 | 4 | one | -1 -(1 row) - --- --- semijoin selectivity for <> --- -explain (costs off) -select * from int4_tbl i4, tenk1 a -where exists(select * from tenk1 b - where a.twothousand = b.twothousand and a.fivethous <> b.fivethous) - and i4.f1 = a.tenthous; - QUERY PLAN ----------------------------------------------- - Hash Semi Join - Hash Cond: (a.twothousand = b.twothousand) - Join Filter: (a.fivethous <> b.fivethous) - -> Hash Join - Hash Cond: (a.tenthous = i4.f1) - -> Seq Scan on tenk1 a - -> Hash - -> Seq Scan on int4_tbl i4 - -> Hash - -> Seq Scan on tenk1 b -(10 rows) - --- --- More complicated constructs --- --- --- Multiway full join --- -CREATE TABLE t1 (name TEXT, n INTEGER); -CREATE TABLE t2 (name TEXT, n INTEGER); -CREATE TABLE t3 (name TEXT, n INTEGER); -INSERT INTO t1 VALUES ( 'bb', 11 ); -INSERT INTO t2 VALUES ( 'bb', 12 ); -INSERT INTO t2 VALUES ( 'cc', 22 ); -INSERT INTO t2 VALUES ( 'ee', 42 ); -INSERT INTO t3 VALUES ( 'bb', 13 ); -INSERT INTO t3 VALUES ( 'cc', 23 ); -INSERT INTO t3 VALUES ( 'dd', 33 ); -SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); - name | n | n | n -------+----+----+---- - bb | 11 | 12 | 13 - cc | | 22 | 23 - dd | | | 33 - ee | | 42 | -(4 rows) - --- --- Test interactions of join syntax and subqueries --- --- Basic cases (we expect planner to pull up the subquery here) -SELECT * FROM -(SELECT * FROM t2) as s2 -INNER JOIN -(SELECT * FROM t3) s3 -USING (name); - name | n | n -------+----+---- - bb | 12 | 13 - cc | 22 | 23 -(2 rows) - -SELECT * FROM -(SELECT * FROM t2) as s2 -LEFT JOIN -(SELECT * FROM t3) s3 -USING (name); - name | n | n -------+----+---- - bb | 12 | 13 - cc | 22 | 23 - ee | 42 | -(3 rows) - -SELECT * FROM -(SELECT * FROM t2) as s2 -FULL JOIN -(SELECT * FROM t3) s3 -USING (name); - name | n | n -------+----+---- - bb | 12 | 13 - cc | 22 | 23 - dd | | 33 - ee | 42 | -(4 rows) - --- Cases with non-nullable expressions in subquery results; --- make sure these go to null as expected -SELECT * FROM -(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 -NATURAL INNER JOIN -(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; - name | s2_n | s2_2 | s3_n | s3_2 -------+------+------+------+------ - bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 -(2 rows) - -SELECT * FROM -(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 -NATURAL LEFT JOIN -(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; - name | s2_n | s2_2 | s3_n | s3_2 -------+------+------+------+------ - bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 - ee | 42 | 2 | | -(3 rows) - -SELECT * FROM -(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 -NATURAL FULL JOIN -(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; - name | s2_n | s2_2 | s3_n | s3_2 -------+------+------+------+------ - bb | 12 | 2 | 13 | 3 - cc | 22 | 2 | 23 | 3 - dd | | | 33 | 3 - ee | 42 | 2 | | -(4 rows) - -SELECT * FROM -(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 -NATURAL INNER JOIN -(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 -NATURAL INNER JOIN -(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; - name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 -------+------+------+------+------+------+------ - bb | 11 | 1 | 12 | 2 | 13 | 3 -(1 row) - -SELECT * FROM -(SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 -NATURAL FULL JOIN -(SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 -NATURAL FULL JOIN -(SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; - name | s1_n | s1_1 | s2_n | s2_2 | s3_n | s3_2 -------+------+------+------+------+------+------ - bb | 11 | 1 | 12 | 2 | 13 | 3 - cc | | | 22 | 2 | 23 | 3 - dd | | | | | 33 | 3 - ee | | | 42 | 2 | | -(4 rows) - -SELECT * FROM -(SELECT name, n as s1_n FROM t1) as s1 -NATURAL FULL JOIN - (SELECT * FROM - (SELECT name, n as s2_n FROM t2) as s2 - NATURAL FULL JOIN - (SELECT name, n as s3_n FROM t3) as s3 - ) ss2; - name | s1_n | s2_n | s3_n -------+------+------+------ - bb | 11 | 12 | 13 - cc | | 22 | 23 - dd | | | 33 - ee | | 42 | -(4 rows) - -SELECT * FROM -(SELECT name, n as s1_n FROM t1) as s1 -NATURAL FULL JOIN - (SELECT * FROM - (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 - NATURAL FULL JOIN - (SELECT name, n as s3_n FROM t3) as s3 - ) ss2; - name | s1_n | s2_n | s2_2 | s3_n -------+------+------+------+------ - bb | 11 | 12 | 2 | 13 - cc | | 22 | 2 | 23 - dd | | | | 33 - ee | | 42 | 2 | -(4 rows) - --- Constants as join keys can also be problematic -SELECT * FROM - (SELECT name, n as s1_n FROM t1) as s1 -FULL JOIN - (SELECT name, 2 as s2_n FROM t2) as s2 -ON (s1_n = s2_n); - name | s1_n | name | s2_n -------+------+------+------ - | | bb | 2 - | | cc | 2 - | | ee | 2 - bb | 11 | | -(4 rows) - --- Test for propagation of nullability constraints into sub-joins -create temp table x (x1 int, x2 int); -insert into x values (1,11); -insert into x values (2,22); -insert into x values (3,null); -insert into x values (4,44); -insert into x values (5,null); -create temp table y (y1 int, y2 int); -insert into y values (1,111); -insert into y values (2,222); -insert into y values (3,333); -insert into y values (4,null); -select * from x; - x1 | x2 -----+---- - 1 | 11 - 2 | 22 - 3 | - 4 | 44 - 5 | -(5 rows) - -select * from y; - y1 | y2 -----+----- - 1 | 111 - 2 | 222 - 3 | 333 - 4 | -(4 rows) - -select * from x left join y on (x1 = y1 and x2 is not null); - x1 | x2 | y1 | y2 -----+----+----+----- - 1 | 11 | 1 | 111 - 2 | 22 | 2 | 222 - 3 | | | - 4 | 44 | 4 | - 5 | | | -(5 rows) - -select * from x left join y on (x1 = y1 and y2 is not null); - x1 | x2 | y1 | y2 -----+----+----+----- - 1 | 11 | 1 | 111 - 2 | 22 | 2 | 222 - 3 | | 3 | 333 - 4 | 44 | | - 5 | | | -(5 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 3 | | 3 | 333 | 3 | - 4 | 44 | 4 | | 4 | 44 - 5 | | | | 5 | -(5 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1 and x2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 3 | | 3 | 333 | | - 4 | 44 | 4 | | 4 | 44 - 5 | | | | | -(5 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1 and y2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 3 | | 3 | 333 | 3 | - 4 | 44 | 4 | | | - 5 | | | | | -(5 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1 and xx2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 3 | | 3 | 333 | | - 4 | 44 | 4 | | 4 | 44 - 5 | | | | | -(5 rows) - --- these should NOT give the same answers as above -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1) where (x2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 4 | 44 | 4 | | 4 | 44 -(3 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1) where (y2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 3 | | 3 | 333 | 3 | -(3 rows) - -select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) -on (x1 = xx1) where (xx2 is not null); - x1 | x2 | y1 | y2 | xx1 | xx2 -----+----+----+-----+-----+----- - 1 | 11 | 1 | 111 | 1 | 11 - 2 | 22 | 2 | 222 | 2 | 22 - 4 | 44 | 4 | | 4 | 44 -(3 rows) - --- --- regression test: check for bug with propagation of implied equality --- to outside an IN --- -select count(*) from tenk1 a where unique1 in - (select unique1 from tenk1 b join tenk1 c using (unique1) - where b.unique2 = 42); - count -------- - 1 -(1 row) - --- --- regression test: check for failure to generate a plan with multiple --- degenerate IN clauses --- -select count(*) from tenk1 x where - x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and - x.unique1 = 0 and - x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); - count -------- - 1 -(1 row) - --- try that with GEQO too -begin; -set geqo = on; -set geqo_threshold = 2; -select count(*) from tenk1 x where - x.unique1 in (select a.f1 from int4_tbl a,float8_tbl b where a.f1=b.f1) and - x.unique1 = 0 and - x.unique1 in (select aa.f1 from int4_tbl aa,float8_tbl bb where aa.f1=bb.f1); - count -------- - 1 -(1 row) - -rollback; --- --- regression test: be sure we cope with proven-dummy append rels --- -explain (costs off) -select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 - where bb < bb and bb is null; - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - -select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 - where bb < bb and bb is null; - aa | bb | unique1 | unique1 -----+----+---------+--------- -(0 rows) - --- --- regression test: check handling of empty-FROM subquery underneath outer join --- -explain (costs off) -select * from int8_tbl i1 left join (int8_tbl i2 join - (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 -order by 1, 2; - QUERY PLAN -------------------------------------------- - Sort - Sort Key: i1.q1, i1.q2 - -> Hash Left Join - Hash Cond: (i1.q2 = i2.q2) - -> Seq Scan on int8_tbl i1 - -> Hash - -> Seq Scan on int8_tbl i2 - Filter: (q1 = 123) -(8 rows) - -select * from int8_tbl i1 left join (int8_tbl i2 join - (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 -order by 1, 2; - q1 | q2 | q1 | q2 | x -------------------+-------------------+-----+------------------+----- - 123 | 456 | 123 | 456 | 123 - 123 | 4567890123456789 | 123 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | - 4567890123456789 | 123 | | | - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 123 -(5 rows) - --- --- regression test: check a case where join_clause_is_movable_into() gives --- an imprecise result, causing an assertion failure --- -select count(*) -from - (select t3.tenthous as x1, coalesce(t1.stringu1, t2.stringu1) as x2 - from tenk1 t1 - left join tenk1 t2 on t1.unique1 = t2.unique1 - join tenk1 t3 on t1.unique2 = t3.unique2) ss, - tenk1 t4, - tenk1 t5 -where t4.thousand = t5.unique1 and ss.x1 = t4.tenthous and ss.x2 = t5.stringu1; - count -------- - 1000 -(1 row) - --- --- regression test: check a case where we formerly missed including an EC --- enforcement clause because it was expected to be handled at scan level --- -explain (costs off) -select a.f1, b.f1, t.thousand, t.tenthous from - tenk1 t, - (select sum(f1)+1 as f1 from int4_tbl i4a) a, - (select sum(f1) as f1 from int4_tbl i4b) b -where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Nested Loop - -> Aggregate - -> Seq Scan on int4_tbl i4b - -> Nested Loop - Join Filter: ((sum(i4b.f1)) = ((sum(i4a.f1) + 1))) - -> Aggregate - -> Seq Scan on int4_tbl i4a - -> Index Only Scan using tenk1_thous_tenthous on tenk1 t - Index Cond: ((thousand = (sum(i4b.f1))) AND (tenthous = ((((sum(i4a.f1) + 1)) + (sum(i4b.f1))) + 999))) -(9 rows) - -select a.f1, b.f1, t.thousand, t.tenthous from - tenk1 t, - (select sum(f1)+1 as f1 from int4_tbl i4a) a, - (select sum(f1) as f1 from int4_tbl i4b) b -where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; - f1 | f1 | thousand | tenthous -----+----+----------+---------- -(0 rows) - --- --- check a case where we formerly got confused by conflicting sort orders --- in redundant merge join path keys --- -explain (costs off) -select * from - j1_tbl full join - (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl - on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; - QUERY PLAN ------------------------------------------------------------------ - Merge Full Join - Merge Cond: ((j2_tbl.i = j1_tbl.i) AND (j2_tbl.k = j1_tbl.i)) - -> Sort - Sort Key: j2_tbl.i DESC, j2_tbl.k - -> Seq Scan on j2_tbl - -> Sort - Sort Key: j1_tbl.i DESC - -> Seq Scan on j1_tbl -(8 rows) - -select * from - j1_tbl full join - (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl - on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; - i | j | t | i | k ----+---+-------+---+---- - | | | | 0 - | | | | - | 0 | zero | | - | | null | | - 8 | 8 | eight | | - 7 | 7 | seven | | - 6 | 6 | six | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | - 4 | 1 | four | | - | | | 3 | -3 - 3 | 2 | three | | - 2 | 3 | two | 2 | 2 - | | | 2 | 4 - | | | 1 | -1 - | | | 0 | - 1 | 4 | one | | - 0 | | zero | | -(19 rows) - --- --- a different check for handling of redundant sort keys in merge joins --- -explain (costs off) -select count(*) from - (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x - left join - (select * from tenk1 y order by y.unique2) y - on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; - QUERY PLAN ----------------------------------------------------------------------------------- - Aggregate - -> Merge Left Join - Merge Cond: (x.thousand = y.unique2) - Join Filter: ((x.twothousand = y.hundred) AND (x.fivethous = y.unique2)) - -> Sort - Sort Key: x.thousand, x.twothousand, x.fivethous - -> Seq Scan on tenk1 x - -> Materialize - -> Index Scan using tenk1_unique2 on tenk1 y -(9 rows) - -select count(*) from - (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x - left join - (select * from tenk1 y order by y.unique2) y - on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; - count -------- - 10000 -(1 row) - --- --- Clean up --- -DROP TABLE t1; -DROP TABLE t2; -DROP TABLE t3; -DROP TABLE J1_TBL; -DROP TABLE J2_TBL; --- Both DELETE and UPDATE allow the specification of additional tables --- to "join" against to determine which rows should be modified. -CREATE TEMP TABLE t1 (a int, b int); -CREATE TEMP TABLE t2 (a int, b int); -CREATE TEMP TABLE t3 (x int, y int); -INSERT INTO t1 VALUES (5, 10); -INSERT INTO t1 VALUES (15, 20); -INSERT INTO t1 VALUES (100, 100); -INSERT INTO t1 VALUES (200, 1000); -INSERT INTO t2 VALUES (200, 2000); -INSERT INTO t3 VALUES (5, 20); -INSERT INTO t3 VALUES (6, 7); -INSERT INTO t3 VALUES (7, 8); -INSERT INTO t3 VALUES (500, 100); -DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; -SELECT * FROM t3; - x | y ------+----- - 6 | 7 - 7 | 8 - 500 | 100 -(3 rows) - -DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a; -SELECT * FROM t3; - x | y ----+--- - 6 | 7 - 7 | 8 -(2 rows) - -DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; -SELECT * FROM t3; - x | y ----+--- -(0 rows) - --- Test join against inheritance tree -create temp table t2a () inherits (t2); -insert into t2a values (200, 2001); -select * from t1 left join t2 on (t1.a = t2.a); - a | b | a | b ------+------+-----+------ - 5 | 10 | | - 15 | 20 | | - 100 | 100 | | - 200 | 1000 | 200 | 2000 - 200 | 1000 | 200 | 2001 -(5 rows) - --- Test matching of column name with wrong alias -select t1.x from t1 join t3 on (t1.a = t3.x); -ERROR: column t1.x does not exist -LINE 1: select t1.x from t1 join t3 on (t1.a = t3.x); - ^ -HINT: Perhaps you meant to reference the column "t3.x". --- --- regression test for 8.1 merge right join bug --- -CREATE TEMP TABLE tt1 ( tt1_id int4, joincol int4 ); -INSERT INTO tt1 VALUES (1, 11); -INSERT INTO tt1 VALUES (2, NULL); -CREATE TEMP TABLE tt2 ( tt2_id int4, joincol int4 ); -INSERT INTO tt2 VALUES (21, 11); -INSERT INTO tt2 VALUES (22, 11); -set enable_hashjoin to off; -set enable_nestloop to off; --- these should give the same results -select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; - tt1_id | joincol | tt2_id | joincol ---------+---------+--------+--------- - 1 | 11 | 21 | 11 - 1 | 11 | 22 | 11 - 2 | | | -(3 rows) - -select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; - tt1_id | joincol | tt2_id | joincol ---------+---------+--------+--------- - 1 | 11 | 21 | 11 - 1 | 11 | 22 | 11 - 2 | | | -(3 rows) - -reset enable_hashjoin; -reset enable_nestloop; --- --- regression test for bug #13908 (hash join with skew tuples & nbatch increase) --- -set work_mem to '64kB'; -set enable_mergejoin to off; -explain (costs off) -select count(*) from tenk1 a, tenk1 b - where a.hundred = b.thousand and (b.fivethous % 10) < 10; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Hash Join - Hash Cond: (a.hundred = b.thousand) - -> Index Only Scan using tenk1_hundred on tenk1 a - -> Hash - -> Seq Scan on tenk1 b - Filter: ((fivethous % 10) < 10) -(7 rows) - -select count(*) from tenk1 a, tenk1 b - where a.hundred = b.thousand and (b.fivethous % 10) < 10; - count --------- - 100000 -(1 row) - -reset work_mem; -reset enable_mergejoin; --- --- regression test for 8.2 bug with improper re-ordering of left joins --- -create temp table tt3(f1 int, f2 text); -insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; -create index tt3i on tt3(f1); -analyze tt3; -create temp table tt4(f1 int); -insert into tt4 values (0),(1),(9999); -analyze tt4; -SELECT a.f1 -FROM tt4 a -LEFT JOIN ( - SELECT b.f1 - FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) - WHERE c.f1 IS NULL -) AS d ON (a.f1 = d.f1) -WHERE d.f1 IS NULL; - f1 ------- - 0 - 1 - 9999 -(3 rows) - --- --- regression test for proper handling of outer joins within antijoins --- -create temp table tt4x(c1 int, c2 int, c3 int); -explain (costs off) -select * from tt4x t1 -where not exists ( - select 1 from tt4x t2 - left join tt4x t3 on t2.c3 = t3.c1 - left join ( select t5.c1 as c1 - from tt4x t4 left join tt4x t5 on t4.c2 = t5.c1 - ) a1 on t3.c2 = a1.c1 - where t1.c1 = t2.c2 -); - QUERY PLAN ---------------------------------------------------------- - Hash Anti Join - Hash Cond: (t1.c1 = t2.c2) - -> Seq Scan on tt4x t1 - -> Hash - -> Merge Right Join - Merge Cond: (t5.c1 = t3.c2) - -> Merge Join - Merge Cond: (t4.c2 = t5.c1) - -> Sort - Sort Key: t4.c2 - -> Seq Scan on tt4x t4 - -> Sort - Sort Key: t5.c1 - -> Seq Scan on tt4x t5 - -> Sort - Sort Key: t3.c2 - -> Merge Left Join - Merge Cond: (t2.c3 = t3.c1) - -> Sort - Sort Key: t2.c3 - -> Seq Scan on tt4x t2 - -> Sort - Sort Key: t3.c1 - -> Seq Scan on tt4x t3 -(24 rows) - --- --- regression test for problems of the sort depicted in bug #3494 --- -create temp table tt5(f1 int, f2 int); -create temp table tt6(f1 int, f2 int); -insert into tt5 values(1, 10); -insert into tt5 values(1, 11); -insert into tt6 values(1, 9); -insert into tt6 values(1, 2); -insert into tt6 values(2, 9); -select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; - f1 | f2 | f1 | f2 -----+----+----+---- - 1 | 10 | 1 | 9 -(1 row) - --- --- regression test for problems of the sort depicted in bug #3588 --- -create temp table xx (pkxx int); -create temp table yy (pkyy int, pkxx int); -insert into xx values (1); -insert into xx values (2); -insert into xx values (3); -insert into yy values (101, 1); -insert into yy values (201, 2); -insert into yy values (301, NULL); -select yy.pkyy as yy_pkyy, yy.pkxx as yy_pkxx, yya.pkyy as yya_pkyy, - xxa.pkxx as xxa_pkxx, xxb.pkxx as xxb_pkxx -from yy - left join (SELECT * FROM yy where pkyy = 101) as yya ON yy.pkyy = yya.pkyy - left join xx xxa on yya.pkxx = xxa.pkxx - left join xx xxb on coalesce (xxa.pkxx, 1) = xxb.pkxx; - yy_pkyy | yy_pkxx | yya_pkyy | xxa_pkxx | xxb_pkxx ----------+---------+----------+----------+---------- - 101 | 1 | 101 | 1 | 1 - 201 | 2 | | | 1 - 301 | | | | 1 -(3 rows) - --- --- regression test for improper pushing of constants across outer-join clauses --- (as seen in early 8.2.x releases) --- -create temp table zt1 (f1 int primary key); -create temp table zt2 (f2 int primary key); -create temp table zt3 (f3 int primary key); -insert into zt1 values(53); -insert into zt2 values(53); -select * from - zt2 left join zt3 on (f2 = f3) - left join zt1 on (f3 = f1) -where f2 = 53; - f2 | f3 | f1 -----+----+---- - 53 | | -(1 row) - -create temp view zv1 as select *,'dummy'::text AS junk from zt1; -select * from - zt2 left join zt3 on (f2 = f3) - left join zv1 on (f3 = f1) -where f2 = 53; - f2 | f3 | f1 | junk -----+----+----+------ - 53 | | | -(1 row) - --- --- regression test for improper extraction of OR indexqual conditions --- (as seen in early 8.3.x releases) --- -select a.unique2, a.ten, b.tenthous, b.unique2, b.hundred -from tenk1 a left join tenk1 b on a.unique2 = b.tenthous -where a.unique1 = 42 and - ((b.unique2 is null and a.ten = 2) or b.hundred = 3); - unique2 | ten | tenthous | unique2 | hundred ----------+-----+----------+---------+--------- -(0 rows) - --- --- test proper positioning of one-time quals in EXISTS (8.4devel bug) --- -prepare foo(bool) as - select count(*) from tenk1 a left join tenk1 b - on (a.unique2 = b.unique1 and exists - (select 1 from tenk1 c where c.thousand = b.unique2 and $1)); -execute foo(true); - count -------- - 10000 -(1 row) - -execute foo(false); - count -------- - 10000 -(1 row) - --- --- test for sane behavior with noncanonical merge clauses, per bug #4926 --- -begin; -set enable_mergejoin = 1; -set enable_hashjoin = 0; -set enable_nestloop = 0; -create temp table a (i integer); -create temp table b (x integer, y integer); -select * from a left join b on i = x and i = y and x = i; - i | x | y ----+---+--- -(0 rows) - -rollback; --- --- test handling of merge clauses using record_ops --- -begin; -create type mycomptype as (id int, v bigint); -create temp table tidv (idv mycomptype); -create index on tidv (idv); -explain (costs off) -select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; - QUERY PLAN ----------------------------------------------------------- - Merge Join - Merge Cond: (a.idv = b.idv) - -> Index Only Scan using tidv_idv_idx on tidv a - -> Materialize - -> Index Only Scan using tidv_idv_idx on tidv b -(5 rows) - -set enable_mergejoin = 0; -explain (costs off) -select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; - QUERY PLAN ----------------------------------------------------- - Nested Loop - -> Seq Scan on tidv a - -> Index Only Scan using tidv_idv_idx on tidv b - Index Cond: (idv = a.idv) -(4 rows) - -rollback; --- --- test NULL behavior of whole-row Vars, per bug #5025 --- -select t1.q2, count(t2.*) -from int8_tbl t1 left join int8_tbl t2 on (t1.q2 = t2.q1) -group by t1.q2 order by 1; - q2 | count --------------------+------- - -4567890123456789 | 0 - 123 | 2 - 456 | 0 - 4567890123456789 | 6 -(4 rows) - -select t1.q2, count(t2.*) -from int8_tbl t1 left join (select * from int8_tbl) t2 on (t1.q2 = t2.q1) -group by t1.q2 order by 1; - q2 | count --------------------+------- - -4567890123456789 | 0 - 123 | 2 - 456 | 0 - 4567890123456789 | 6 -(4 rows) - -select t1.q2, count(t2.*) -from int8_tbl t1 left join (select * from int8_tbl offset 0) t2 on (t1.q2 = t2.q1) -group by t1.q2 order by 1; - q2 | count --------------------+------- - -4567890123456789 | 0 - 123 | 2 - 456 | 0 - 4567890123456789 | 6 -(4 rows) - -select t1.q2, count(t2.*) -from int8_tbl t1 left join - (select q1, case when q2=1 then 1 else q2 end as q2 from int8_tbl) t2 - on (t1.q2 = t2.q1) -group by t1.q2 order by 1; - q2 | count --------------------+------- - -4567890123456789 | 0 - 123 | 2 - 456 | 0 - 4567890123456789 | 6 -(4 rows) - --- --- test incorrect failure to NULL pulled-up subexpressions --- -begin; -create temp table a ( - code char not null, - constraint a_pk primary key (code) -); -create temp table b ( - a char not null, - num integer not null, - constraint b_pk primary key (a, num) -); -create temp table c ( - name char not null, - a char, - constraint c_pk primary key (name) -); -insert into a (code) values ('p'); -insert into a (code) values ('q'); -insert into b (a, num) values ('p', 1); -insert into b (a, num) values ('p', 2); -insert into c (name, a) values ('A', 'p'); -insert into c (name, a) values ('B', 'q'); -insert into c (name, a) values ('C', null); -select c.name, ss.code, ss.b_cnt, ss.const -from c left join - (select a.code, coalesce(b_grp.cnt, 0) as b_cnt, -1 as const - from a left join - (select count(1) as cnt, b.a from b group by b.a) as b_grp - on a.code = b_grp.a - ) as ss - on (c.a = ss.code) -order by c.name; - name | code | b_cnt | const -------+------+-------+------- - A | p | 2 | -1 - B | q | 0 | -1 - C | | | -(3 rows) - -rollback; --- --- test incorrect handling of placeholders that only appear in targetlists, --- per bug #6154 --- -SELECT * FROM -( SELECT 1 as key1 ) sub1 -LEFT JOIN -( SELECT sub3.key3, sub4.value2, COALESCE(sub4.value2, 66) as value3 FROM - ( SELECT 1 as key3 ) sub3 - LEFT JOIN - ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM - ( SELECT 1 as key5 ) sub5 - LEFT JOIN - ( SELECT 2 as key6, 42 as value1 ) sub6 - ON sub5.key5 = sub6.key6 - ) sub4 - ON sub4.key5 = sub3.key3 -) sub2 -ON sub1.key1 = sub2.key3; - key1 | key3 | value2 | value3 -------+------+--------+-------- - 1 | 1 | 1 | 1 -(1 row) - --- test the path using join aliases, too -SELECT * FROM -( SELECT 1 as key1 ) sub1 -LEFT JOIN -( SELECT sub3.key3, value2, COALESCE(value2, 66) as value3 FROM - ( SELECT 1 as key3 ) sub3 - LEFT JOIN - ( SELECT sub5.key5, COALESCE(sub6.value1, 1) as value2 FROM - ( SELECT 1 as key5 ) sub5 - LEFT JOIN - ( SELECT 2 as key6, 42 as value1 ) sub6 - ON sub5.key5 = sub6.key6 - ) sub4 - ON sub4.key5 = sub3.key3 -) sub2 -ON sub1.key1 = sub2.key3; - key1 | key3 | value2 | value3 -------+------+--------+-------- - 1 | 1 | 1 | 1 -(1 row) - --- --- test case where a PlaceHolderVar is used as a nestloop parameter --- -EXPLAIN (COSTS OFF) -SELECT qq, unique1 - FROM - ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 - FULL OUTER JOIN - ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 - USING (qq) - INNER JOIN tenk1 c ON qq = unique2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Nested Loop - -> Hash Full Join - Hash Cond: ((COALESCE(a.q1, '0'::bigint)) = (COALESCE(b.q2, '-1'::bigint))) - -> Seq Scan on int8_tbl a - -> Hash - -> Seq Scan on int8_tbl b - -> Index Scan using tenk1_unique2 on tenk1 c - Index Cond: (unique2 = COALESCE((COALESCE(a.q1, '0'::bigint)), (COALESCE(b.q2, '-1'::bigint)))) -(8 rows) - -SELECT qq, unique1 - FROM - ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 - FULL OUTER JOIN - ( SELECT COALESCE(q2, -1) AS qq FROM int8_tbl b ) AS ss2 - USING (qq) - INNER JOIN tenk1 c ON qq = unique2; - qq | unique1 ------+--------- - 123 | 4596 - 123 | 4596 - 456 | 7318 -(3 rows) - --- --- nested nestloops can require nested PlaceHolderVars --- -create temp table nt1 ( - id int primary key, - a1 boolean, - a2 boolean -); -create temp table nt2 ( - id int primary key, - nt1_id int, - b1 boolean, - b2 boolean, - foreign key (nt1_id) references nt1(id) -); -create temp table nt3 ( - id int primary key, - nt2_id int, - c1 boolean, - foreign key (nt2_id) references nt2(id) -); -insert into nt1 values (1,true,true); -insert into nt1 values (2,true,false); -insert into nt1 values (3,false,false); -insert into nt2 values (1,1,true,true); -insert into nt2 values (2,2,true,false); -insert into nt2 values (3,3,false,false); -insert into nt3 values (1,1,true); -insert into nt3 values (2,2,false); -insert into nt3 values (3,3,true); -explain (costs off) -select nt3.id -from nt3 as nt3 - left join - (select nt2.*, (nt2.b1 and ss1.a3) AS b3 - from nt2 as nt2 - left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 - on ss1.id = nt2.nt1_id - ) as ss2 - on ss2.id = nt3.nt2_id -where nt3.id = 1 and ss2.b3; - QUERY PLAN ------------------------------------------------ - Nested Loop - -> Nested Loop - -> Index Scan using nt3_pkey on nt3 - Index Cond: (id = 1) - -> Index Scan using nt2_pkey on nt2 - Index Cond: (id = nt3.nt2_id) - -> Index Only Scan using nt1_pkey on nt1 - Index Cond: (id = nt2.nt1_id) - Filter: (nt2.b1 AND (id IS NOT NULL)) -(9 rows) - -select nt3.id -from nt3 as nt3 - left join - (select nt2.*, (nt2.b1 and ss1.a3) AS b3 - from nt2 as nt2 - left join - (select nt1.*, (nt1.id is not null) as a3 from nt1) as ss1 - on ss1.id = nt2.nt1_id - ) as ss2 - on ss2.id = nt3.nt2_id -where nt3.id = 1 and ss2.b3; - id ----- - 1 -(1 row) - --- --- test case where a PlaceHolderVar is propagated into a subquery --- -explain (costs off) -select * from - int8_tbl t1 left join - (select q1 as x, 42 as y from int8_tbl t2) ss - on t1.q2 = ss.x -where - 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) -order by 1,2; - QUERY PLAN ------------------------------------------------------------ - Sort - Sort Key: t1.q1, t1.q2 - -> Hash Left Join - Hash Cond: (t1.q2 = t2.q1) - Filter: (1 = (SubPlan 1)) - -> Seq Scan on int8_tbl t1 - -> Hash - -> Seq Scan on int8_tbl t2 - SubPlan 1 - -> Limit - -> Result - One-Time Filter: ((42) IS NOT NULL) - -> Seq Scan on int8_tbl t3 -(13 rows) - -select * from - int8_tbl t1 left join - (select q1 as x, 42 as y from int8_tbl t2) ss - on t1.q2 = ss.x -where - 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) -order by 1,2; - q1 | q2 | x | y -------------------+------------------+------------------+---- - 123 | 4567890123456789 | 4567890123456789 | 42 - 123 | 4567890123456789 | 4567890123456789 | 42 - 123 | 4567890123456789 | 4567890123456789 | 42 - 4567890123456789 | 123 | 123 | 42 - 4567890123456789 | 123 | 123 | 42 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 42 -(8 rows) - --- --- variant where a PlaceHolderVar is needed at a join, but not above the join --- -explain (costs off) -select * from - int4_tbl as i41, - lateral - (select 1 as x from - (select i41.f1 as lat, - i42.f1 as loc from - int8_tbl as i81, int4_tbl as i42) as ss1 - right join int4_tbl as i43 on (i43.f1 > 1) - where ss1.loc = ss1.lat) as ss2 -where i41.f1 > 0; - QUERY PLAN --------------------------------------------------- - Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl i41 - Filter: (f1 > 0) - -> Nested Loop - Join Filter: (i41.f1 = i42.f1) - -> Seq Scan on int8_tbl i81 - -> Materialize - -> Seq Scan on int4_tbl i42 - -> Materialize - -> Seq Scan on int4_tbl i43 - Filter: (f1 > 1) -(12 rows) - -select * from - int4_tbl as i41, - lateral - (select 1 as x from - (select i41.f1 as lat, - i42.f1 as loc from - int8_tbl as i81, int4_tbl as i42) as ss1 - right join int4_tbl as i43 on (i43.f1 > 1) - where ss1.loc = ss1.lat) as ss2 -where i41.f1 > 0; - f1 | x -------------+--- - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 123456 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 - 2147483647 | 1 -(20 rows) - --- --- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE --- -select * from int4_tbl a full join int4_tbl b on true; - f1 | f1 --------------+------------- - 0 | 0 - 0 | 123456 - 0 | -123456 - 0 | 2147483647 - 0 | -2147483647 - 123456 | 0 - 123456 | 123456 - 123456 | -123456 - 123456 | 2147483647 - 123456 | -2147483647 - -123456 | 0 - -123456 | 123456 - -123456 | -123456 - -123456 | 2147483647 - -123456 | -2147483647 - 2147483647 | 0 - 2147483647 | 123456 - 2147483647 | -123456 - 2147483647 | 2147483647 - 2147483647 | -2147483647 - -2147483647 | 0 - -2147483647 | 123456 - -2147483647 | -123456 - -2147483647 | 2147483647 - -2147483647 | -2147483647 -(25 rows) - -select * from int4_tbl a full join int4_tbl b on false; - f1 | f1 --------------+------------- - | 0 - | 123456 - | -123456 - | 2147483647 - | -2147483647 - 0 | - 123456 | - -123456 | - 2147483647 | - -2147483647 | -(10 rows) - --- --- test for ability to use a cartesian join when necessary --- -create temp table q1 as select 1 as q1; -create temp table q2 as select 0 as q2; -analyze q1; -analyze q2; -explain (costs off) -select * from - tenk1 join int4_tbl on f1 = twothousand, - q1, q2 -where q1 = thousand or q2 = thousand; - QUERY PLAN ------------------------------------------------------------------------- - Hash Join - Hash Cond: (tenk1.twothousand = int4_tbl.f1) - -> Nested Loop - -> Nested Loop - -> Seq Scan on q1 - -> Seq Scan on q2 - -> Bitmap Heap Scan on tenk1 - Recheck Cond: ((q1.q1 = thousand) OR (q2.q2 = thousand)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = q1.q1) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = q2.q2) - -> Hash - -> Seq Scan on int4_tbl -(15 rows) - -explain (costs off) -select * from - tenk1 join int4_tbl on f1 = twothousand, - q1, q2 -where thousand = (q1 + q2); - QUERY PLAN --------------------------------------------------------------- - Hash Join - Hash Cond: (tenk1.twothousand = int4_tbl.f1) - -> Nested Loop - -> Nested Loop - -> Seq Scan on q1 - -> Seq Scan on q2 - -> Bitmap Heap Scan on tenk1 - Recheck Cond: (thousand = (q1.q1 + q2.q2)) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = (q1.q1 + q2.q2)) - -> Hash - -> Seq Scan on int4_tbl -(12 rows) - --- --- test ability to generate a suitable plan for a star-schema query --- -explain (costs off) -select * from - tenk1, int8_tbl a, int8_tbl b -where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; - QUERY PLAN ---------------------------------------------------------------------- - Nested Loop - -> Seq Scan on int8_tbl b - Filter: (q2 = 2) - -> Nested Loop - -> Seq Scan on int8_tbl a - Filter: (q2 = 1) - -> Index Scan using tenk1_thous_tenthous on tenk1 - Index Cond: ((thousand = a.q1) AND (tenthous = b.q1)) -(8 rows) - --- --- test a corner case in which we shouldn't apply the star-schema optimization --- -explain (costs off) -select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from - tenk1 t1 - inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 - from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) - on v1.x1 = v2.y2) subq1 - on (i1.f1 = subq1.x2) - on (t1.unique2 = subq1.d1) - left join tenk1 t2 - on (subq1.y1 = t2.unique1) -where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------------ - Nested Loop - -> Nested Loop - Join Filter: (t1.stringu1 > t2.stringu2) - -> Nested Loop - -> Nested Loop - -> Seq Scan on onerow - -> Seq Scan on onerow onerow_1 - -> Index Scan using tenk1_unique2 on tenk1 t1 - Index Cond: ((unique2 = (11)) AND (unique2 < 42)) - -> Index Scan using tenk1_unique1 on tenk1 t2 - Index Cond: (unique1 = (3)) - -> Seq Scan on int4_tbl i1 - Filter: (f1 = 0) -(13 rows) - -select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from - tenk1 t1 - inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 - from (select 1,0 from onerow) v1(x1,x2) - left join (select 3,1 from onerow) v2(y1,y2) - on v1.x1 = v2.y2) subq1 - on (i1.f1 = subq1.x2) - on (t1.unique2 = subq1.d1) - left join tenk1 t2 - on (subq1.y1 = t2.unique1) -where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - unique2 | stringu1 | unique1 | stringu2 ----------+----------+---------+---------- - 11 | WFAAAA | 3 | LKIAAA -(1 row) - --- variant that isn't quite a star-schema case -select ss1.d1 from - tenk1 as t1 - inner join tenk1 as t2 - on t1.tenthous = t2.ten - inner join - int8_tbl as i8 - left join int4_tbl as i4 - inner join (select 64::information_schema.cardinal_number as d1 - from tenk1 t3, - lateral (select abs(t3.unique1) + random()) ss0(x) - where t3.fivethous < 0) as ss1 - on i4.f1 = ss1.d1 - on i8.q1 = i4.f1 - on t1.tenthous = ss1.d1 -where t1.unique1 < i4.f1; - d1 ----- -(0 rows) - --- this variant is foldable by the remove-useless-RESULT-RTEs code -explain (costs off) -select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from - tenk1 t1 - inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) - on v1.x1 = v2.y2) subq1 - on (i1.f1 = subq1.x2) - on (t1.unique2 = subq1.d1) - left join tenk1 t2 - on (subq1.y1 = t2.unique1) -where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------ - Nested Loop - Join Filter: (t1.stringu1 > t2.stringu2) - -> Nested Loop - -> Seq Scan on int4_tbl i1 - Filter: (f1 = 0) - -> Index Scan using tenk1_unique2 on tenk1 t1 - Index Cond: ((unique2 = (11)) AND (unique2 < 42)) - -> Index Scan using tenk1_unique1 on tenk1 t2 - Index Cond: (unique1 = (3)) -(9 rows) - -select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from - tenk1 t1 - inner join int4_tbl i1 - left join (select v1.x2, v2.y1, 11 AS d1 - from (values(1,0)) v1(x1,x2) - left join (values(3,1)) v2(y1,y2) - on v1.x1 = v2.y2) subq1 - on (i1.f1 = subq1.x2) - on (t1.unique2 = subq1.d1) - left join tenk1 t2 - on (subq1.y1 = t2.unique1) -where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - unique2 | stringu1 | unique1 | stringu2 ----------+----------+---------+---------- - 11 | WFAAAA | 3 | LKIAAA -(1 row) - --- Here's a variant that we can't fold too aggressively, though, --- or we end up with noplace to evaluate the lateral PHV -explain (verbose, costs off) -select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), - lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ---------------------------- - Nested Loop - Output: 1, (2), ((2)) - -> Result - Output: 2 - -> Limit - Output: ((2)) - -> Result - Output: (2) -(8 rows) - -select * from - (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), - lateral (select ss2.y as z limit 1) ss3; - x | y | z ----+---+--- - 1 | 2 | 2 -(1 row) - --- Test proper handling of appendrel PHVs during useless-RTE removal -explain (costs off) -select * from - (select 0 as z) as t1 - left join - (select true as a) as t2 - on true, - lateral (select true as b - union all - select a as b) as t3 -where b; - QUERY PLAN ---------------------------------------- - Nested Loop - -> Result - -> Append - -> Result - -> Result - One-Time Filter: (true) -(6 rows) - -select * from - (select 0 as z) as t1 - left join - (select true as a) as t2 - on true, - lateral (select true as b - union all - select a as b) as t3 -where b; - z | a | b ----+---+--- - 0 | t | t - 0 | t | t -(2 rows) - --- --- test inlining of immutable functions --- -create function f_immutable_int4(i integer) returns integer as -$$ begin return i; end; $$ language plpgsql immutable; --- check optimization of function scan with join -explain (costs off) -select unique1 from tenk1, (select * from f_immutable_int4(1) x) x -where x = unique1; - QUERY PLAN ----------------------------------------------- - Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(2 rows) - -explain (verbose, costs off) -select unique1, x.* -from tenk1, (select *, random() from f_immutable_int4(1) x) x -where x = unique1; - QUERY PLAN ------------------------------------------------------------ - Nested Loop - Output: tenk1.unique1, (1), (random()) - -> Result - Output: 1, random() - -> Index Only Scan using tenk1_unique1 on public.tenk1 - Output: tenk1.unique1 - Index Cond: (tenk1.unique1 = (1)) -(7 rows) - -explain (costs off) -select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; - QUERY PLAN ----------------------------------------------- - Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(2 rows) - -explain (costs off) -select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; - QUERY PLAN ----------------------------------------------- - Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(2 rows) - -explain (costs off) -select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - -explain (costs off) -select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------- - Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(2 rows) - -explain (costs off) -select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------------- - Nested Loop Left Join - Join Filter: (tenk1.unique1 = 1) - -> Index Only Scan using tenk1_unique1 on tenk1 - -> Materialize - -> Result -(5 rows) - -explain (costs off) -select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------------- - Nested Loop Left Join - -> Result - -> Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(4 rows) - -explain (costs off) -select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ----------------------------------------------------- - Merge Full Join - Merge Cond: (tenk1.unique1 = (1)) - -> Index Only Scan using tenk1_unique1 on tenk1 - -> Sort - Sort Key: (1) - -> Result -(6 rows) - --- check that pullup of a const function allows further const-folding -explain (costs off) -select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - --- test inlining of immutable functions with PlaceHolderVars -explain (costs off) -select nt3.id -from nt3 as nt3 - left join - (select nt2.*, (nt2.b1 or i4 = 42) AS b3 - from nt2 as nt2 - left join - f_immutable_int4(0) i4 - on i4 = nt2.nt1_id - ) as ss2 - on ss2.id = nt3.nt2_id -where nt3.id = 1 and ss2.b3; - QUERY PLAN ----------------------------------------------- - Nested Loop Left Join - Filter: ((nt2.b1 OR ((0) = 42))) - -> Index Scan using nt3_pkey on nt3 - Index Cond: (id = 1) - -> Nested Loop Left Join - Join Filter: (0 = nt2.nt1_id) - -> Index Scan using nt2_pkey on nt2 - Index Cond: (id = nt3.nt2_id) - -> Result -(9 rows) - -drop function f_immutable_int4(int); --- test inlining when function returns composite -create function mki8(bigint, bigint) returns int8_tbl as -$$select row($1,$2)::int8_tbl$$ language sql; -create function mki4(int) returns int4_tbl as -$$select row($1)::int4_tbl$$ language sql; -explain (verbose, costs off) -select * from mki8(1,2); - QUERY PLAN ------------------------------------- - Function Scan on mki8 - Output: q1, q2 - Function Call: '(1,2)'::int8_tbl -(3 rows) - -select * from mki8(1,2); - q1 | q2 -----+---- - 1 | 2 -(1 row) - -explain (verbose, costs off) -select * from mki4(42); - QUERY PLAN ------------------------------------ - Function Scan on mki4 - Output: f1 - Function Call: '(42)'::int4_tbl -(3 rows) - -select * from mki4(42); - f1 ----- - 42 -(1 row) - -drop function mki8(bigint, bigint); -drop function mki4(int); --- --- test extraction of restriction OR clauses from join OR clause --- (we used to only do this for indexable clauses) --- -explain (costs off) -select * from tenk1 a join tenk1 b on - (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.hundred = 4); - QUERY PLAN -------------------------------------------------------------------------------------------------- - Nested Loop - Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = 3) AND (b.hundred = 4))) - -> Bitmap Heap Scan on tenk1 b - Recheck Cond: ((unique1 = 2) OR (hundred = 4)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_unique1 - Index Cond: (unique1 = 2) - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred = 4) - -> Materialize - -> Bitmap Heap Scan on tenk1 a - Recheck Cond: ((unique1 = 1) OR (unique2 = 3)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_unique1 - Index Cond: (unique1 = 1) - -> Bitmap Index Scan on tenk1_unique2 - Index Cond: (unique2 = 3) -(17 rows) - -explain (costs off) -select * from tenk1 a join tenk1 b on - (a.unique1 = 1 and b.unique1 = 2) or (a.unique2 = 3 and b.ten = 4); - QUERY PLAN ---------------------------------------------------------------------------------------------- - Nested Loop - Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR ((a.unique2 = 3) AND (b.ten = 4))) - -> Seq Scan on tenk1 b - Filter: ((unique1 = 2) OR (ten = 4)) - -> Materialize - -> Bitmap Heap Scan on tenk1 a - Recheck Cond: ((unique1 = 1) OR (unique2 = 3)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_unique1 - Index Cond: (unique1 = 1) - -> Bitmap Index Scan on tenk1_unique2 - Index Cond: (unique2 = 3) -(12 rows) - -explain (costs off) -select * from tenk1 a join tenk1 b on - (a.unique1 = 1 and b.unique1 = 2) or - ((a.unique2 = 3 or a.unique2 = 7) and b.hundred = 4); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Nested Loop - Join Filter: (((a.unique1 = 1) AND (b.unique1 = 2)) OR (((a.unique2 = 3) OR (a.unique2 = 7)) AND (b.hundred = 4))) - -> Bitmap Heap Scan on tenk1 b - Recheck Cond: ((unique1 = 2) OR (hundred = 4)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_unique1 - Index Cond: (unique1 = 2) - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred = 4) - -> Materialize - -> Bitmap Heap Scan on tenk1 a - Recheck Cond: ((unique1 = 1) OR (unique2 = 3) OR (unique2 = 7)) - -> BitmapOr - -> Bitmap Index Scan on tenk1_unique1 - Index Cond: (unique1 = 1) - -> Bitmap Index Scan on tenk1_unique2 - Index Cond: (unique2 = 3) - -> Bitmap Index Scan on tenk1_unique2 - Index Cond: (unique2 = 7) -(19 rows) - --- --- test placement of movable quals in a parameterized join tree --- -explain (costs off) -select * from tenk1 t1 left join - (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) - on t1.hundred = t2.hundred and t1.ten = t3.ten -where t1.unique1 = 1; - QUERY PLAN --------------------------------------------------------- - Nested Loop Left Join - -> Index Scan using tenk1_unique1 on tenk1 t1 - Index Cond: (unique1 = 1) - -> Nested Loop - Join Filter: (t1.ten = t3.ten) - -> Bitmap Heap Scan on tenk1 t2 - Recheck Cond: (t1.hundred = hundred) - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred = t1.hundred) - -> Index Scan using tenk1_unique2 on tenk1 t3 - Index Cond: (unique2 = t2.thousand) -(11 rows) - -explain (costs off) -select * from tenk1 t1 left join - (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) - on t1.hundred = t2.hundred and t1.ten + t2.ten = t3.ten -where t1.unique1 = 1; - QUERY PLAN --------------------------------------------------------- - Nested Loop Left Join - -> Index Scan using tenk1_unique1 on tenk1 t1 - Index Cond: (unique1 = 1) - -> Nested Loop - Join Filter: ((t1.ten + t2.ten) = t3.ten) - -> Bitmap Heap Scan on tenk1 t2 - Recheck Cond: (t1.hundred = hundred) - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred = t1.hundred) - -> Index Scan using tenk1_unique2 on tenk1 t3 - Index Cond: (unique2 = t2.thousand) -(11 rows) - -explain (costs off) -select count(*) from - tenk1 a join tenk1 b on a.unique1 = b.unique2 - left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand - join int4_tbl on b.thousand = f1; - QUERY PLAN -------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: (a.unique2 = b.unique1) - -> Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl - -> Bitmap Heap Scan on tenk1 b - Recheck Cond: (thousand = int4_tbl.f1) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = int4_tbl.f1) - -> Index Scan using tenk1_unique1 on tenk1 a - Index Cond: (unique1 = b.unique2) - -> Index Only Scan using tenk1_thous_tenthous on tenk1 c - Index Cond: (thousand = a.thousand) -(14 rows) - -select count(*) from - tenk1 a join tenk1 b on a.unique1 = b.unique2 - left join tenk1 c on a.unique2 = b.unique1 and c.thousand = a.thousand - join int4_tbl on b.thousand = f1; - count -------- - 10 -(1 row) - -explain (costs off) -select b.unique1 from - tenk1 a join tenk1 b on a.unique1 = b.unique2 - left join tenk1 c on b.unique1 = 42 and c.thousand = a.thousand - join int4_tbl i1 on b.thousand = f1 - right join int4_tbl i2 on i2.f1 = b.tenthous - order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------ - Sort - Sort Key: b.unique1 - -> Nested Loop Left Join - -> Seq Scan on int4_tbl i2 - -> Nested Loop Left Join - Join Filter: (b.unique1 = 42) - -> Nested Loop - -> Nested Loop - -> Seq Scan on int4_tbl i1 - -> Index Scan using tenk1_thous_tenthous on tenk1 b - Index Cond: ((thousand = i1.f1) AND (tenthous = i2.f1)) - -> Index Scan using tenk1_unique1 on tenk1 a - Index Cond: (unique1 = b.unique2) - -> Index Only Scan using tenk1_thous_tenthous on tenk1 c - Index Cond: (thousand = a.thousand) -(15 rows) - -select b.unique1 from - tenk1 a join tenk1 b on a.unique1 = b.unique2 - left join tenk1 c on b.unique1 = 42 and c.thousand = a.thousand - join int4_tbl i1 on b.thousand = f1 - right join int4_tbl i2 on i2.f1 = b.tenthous - order by 1; - unique1 ---------- - 0 - - - - -(5 rows) - -explain (costs off) -select * from -( - select unique1, q1, coalesce(unique1, -1) + q1 as fault - from int8_tbl left join tenk1 on (q2 = unique2) -) ss -where fault = 122 -order by fault; - QUERY PLAN --------------------------------------------------------------------------- - Nested Loop Left Join - Filter: ((COALESCE(tenk1.unique1, '-1'::integer) + int8_tbl.q1) = 122) - -> Seq Scan on int8_tbl - -> Index Scan using tenk1_unique2 on tenk1 - Index Cond: (unique2 = int8_tbl.q2) -(5 rows) - -select * from -( - select unique1, q1, coalesce(unique1, -1) + q1 as fault - from int8_tbl left join tenk1 on (q2 = unique2) -) ss -where fault = 122 -order by fault; - unique1 | q1 | fault ----------+-----+------- - | 123 | 122 -(1 row) - -explain (costs off) -select * from -(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) -left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x -left join unnest(v1ys) as u1(u1y) on u1y = v2y; - QUERY PLAN -------------------------------------------------------------- - Nested Loop Left Join - -> Values Scan on "*VALUES*" - -> Hash Right Join - Hash Cond: (u1.u1y = "*VALUES*_1".column2) - Filter: ("*VALUES*_1".column1 = "*VALUES*".column1) - -> Function Scan on unnest u1 - -> Hash - -> Values Scan on "*VALUES*_1" -(8 rows) - -select * from -(values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) -left join (values (1, 10), (2, 20)) as v2(v2x,v2y) on v2x = v1x -left join unnest(v1ys) as u1(u1y) on u1y = v2y; - v1x | v1ys | v2x | v2y | u1y ------+---------+-----+-----+----- - 1 | {10,20} | 1 | 10 | 10 - 2 | {20,30} | 2 | 20 | 20 -(2 rows) - --- --- test handling of potential equivalence clauses above outer joins --- -explain (costs off) -select q1, unique2, thousand, hundred - from int8_tbl a left join tenk1 b on q1 = unique2 - where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); - QUERY PLAN --------------------------------------------------------------------------------------- - Nested Loop Left Join - Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) - -> Seq Scan on int8_tbl a - -> Index Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 = a.q1) -(5 rows) - -select q1, unique2, thousand, hundred - from int8_tbl a left join tenk1 b on q1 = unique2 - where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); - q1 | unique2 | thousand | hundred -----+---------+----------+--------- -(0 rows) - -explain (costs off) -select f1, unique2, case when unique2 is null then f1 else 0 end - from int4_tbl a left join tenk1 b on f1 = unique2 - where (case when unique2 is null then f1 else 0 end) = 0; - QUERY PLAN --------------------------------------------------------------------- - Nested Loop Left Join - Filter: (CASE WHEN (b.unique2 IS NULL) THEN a.f1 ELSE 0 END = 0) - -> Seq Scan on int4_tbl a - -> Index Only Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 = a.f1) -(5 rows) - -select f1, unique2, case when unique2 is null then f1 else 0 end - from int4_tbl a left join tenk1 b on f1 = unique2 - where (case when unique2 is null then f1 else 0 end) = 0; - f1 | unique2 | case -----+---------+------ - 0 | 0 | 0 -(1 row) - --- --- another case with equivalence clauses above outer joins (bug #8591) --- -explain (costs off) -select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) - from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) - where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Nested Loop Left Join - -> Nested Loop Left Join - Filter: (COALESCE(b.twothousand, a.twothousand) = 44) - -> Index Scan using tenk1_unique2 on tenk1 a - Index Cond: (unique2 < 10) - -> Bitmap Heap Scan on tenk1 b - Recheck Cond: (thousand = a.unique1) - -> Bitmap Index Scan on tenk1_thous_tenthous - Index Cond: (thousand = a.unique1) - -> Index Scan using tenk1_unique2 on tenk1 c - Index Cond: ((unique2 = COALESCE(b.twothousand, a.twothousand)) AND (unique2 = 44)) -(11 rows) - -select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) - from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) - where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; - unique1 | unique1 | unique1 | coalesce ----------+---------+---------+---------- -(0 rows) - --- --- check handling of join aliases when flattening multiple levels of subquery --- -explain (verbose, costs off) -select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from - (values (0),(1)) foo1(join_key) -left join - (select join_key, bug_field from - (select ss1.join_key, ss1.bug_field from - (select f1 as join_key, 666 as bug_field from int4_tbl i1) ss1 - ) foo2 - left join - (select unique2 as join_key from tenk1 i2) ss2 - using (join_key) - ) foo3 -using (join_key); - QUERY PLAN --------------------------------------------------------------------------- - Nested Loop Left Join - Output: "*VALUES*".column1, i1.f1, (666) - Join Filter: ("*VALUES*".column1 = i1.f1) - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1 - -> Materialize - Output: i1.f1, (666) - -> Nested Loop Left Join - Output: i1.f1, 666 - -> Seq Scan on public.int4_tbl i1 - Output: i1.f1 - -> Index Only Scan using tenk1_unique2 on public.tenk1 i2 - Output: i2.unique2 - Index Cond: (i2.unique2 = i1.f1) -(14 rows) - -select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from - (values (0),(1)) foo1(join_key) -left join - (select join_key, bug_field from - (select ss1.join_key, ss1.bug_field from - (select f1 as join_key, 666 as bug_field from int4_tbl i1) ss1 - ) foo2 - left join - (select unique2 as join_key from tenk1 i2) ss2 - using (join_key) - ) foo3 -using (join_key); - foo1_id | foo3_id | bug_field ----------+---------+----------- - 0 | 0 | 666 - 1 | | -(2 rows) - --- --- test successful handling of nested outer joins with degenerate join quals --- -explain (verbose, costs off) -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------- - Hash Left Join - Output: t1.f1 - Hash Cond: (i8.q2 = i4.f1) - -> Nested Loop Left Join - Output: t1.f1, i8.q2 - Join Filter: (t1.f1 = '***'::text) - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - -> Materialize - Output: i8.q2 - -> Hash Right Join - Output: i8.q2 - Hash Cond: ((NULL::integer) = i8b1.q2) - -> Hash Join - Output: i8.q2, (NULL::integer) - Hash Cond: (i8.q1 = i8b2.q1) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Hash - Output: i8b2.q1, (NULL::integer) - -> Seq Scan on public.int8_tbl i8b2 - Output: i8b2.q1, NULL::integer - -> Hash - Output: i8b1.q2 - -> Seq Scan on public.int8_tbl i8b1 - Output: i8b1.q2 - -> Hash - Output: i4.f1 - -> Seq Scan on public.int4_tbl i4 - Output: i4.f1 -(30 rows) - -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - f1 -------------------- - doh! - hi de ho neighbor -(2 rows) - -explain (verbose, costs off) -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------------- - Hash Left Join - Output: t1.f1 - Hash Cond: (i8.q2 = i4.f1) - -> Nested Loop Left Join - Output: t1.f1, i8.q2 - Join Filter: (t1.f1 = '***'::text) - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - -> Materialize - Output: i8.q2 - -> Hash Right Join - Output: i8.q2 - Hash Cond: ((NULL::integer) = i8b1.q2) - -> Hash Right Join - Output: i8.q2, (NULL::integer) - Hash Cond: (i8b2.q1 = i8.q1) - -> Nested Loop - Output: i8b2.q1, NULL::integer - -> Seq Scan on public.int8_tbl i8b2 - Output: i8b2.q1, i8b2.q2 - -> Materialize - -> Seq Scan on public.int4_tbl i4b2 - -> Hash - Output: i8.q1, i8.q2 - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Hash - Output: i8b1.q2 - -> Seq Scan on public.int8_tbl i8b1 - Output: i8b1.q2 - -> Hash - Output: i4.f1 - -> Seq Scan on public.int4_tbl i4 - Output: i4.f1 -(34 rows) - -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - f1 -------------------- - doh! - hi de ho neighbor -(2 rows) - -explain (verbose, costs off) -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2 - where q1 = f1) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - QUERY PLAN ----------------------------------------------------------------------------- - Hash Left Join - Output: t1.f1 - Hash Cond: (i8.q2 = i4.f1) - -> Nested Loop Left Join - Output: t1.f1, i8.q2 - Join Filter: (t1.f1 = '***'::text) - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - -> Materialize - Output: i8.q2 - -> Hash Right Join - Output: i8.q2 - Hash Cond: ((NULL::integer) = i8b1.q2) - -> Hash Right Join - Output: i8.q2, (NULL::integer) - Hash Cond: (i8b2.q1 = i8.q1) - -> Hash Join - Output: i8b2.q1, NULL::integer - Hash Cond: (i8b2.q1 = i4b2.f1) - -> Seq Scan on public.int8_tbl i8b2 - Output: i8b2.q1, i8b2.q2 - -> Hash - Output: i4b2.f1 - -> Seq Scan on public.int4_tbl i4b2 - Output: i4b2.f1 - -> Hash - Output: i8.q1, i8.q2 - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Hash - Output: i8b1.q2 - -> Seq Scan on public.int8_tbl i8b1 - Output: i8b1.q2 - -> Hash - Output: i4.f1 - -> Seq Scan on public.int4_tbl i4 - Output: i4.f1 -(37 rows) - -select t1.* from - text_tbl t1 - left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 - left join int8_tbl i8 - left join (select *, null::int as d2 from int8_tbl i8b2, int4_tbl i4b2 - where q1 = f1) b2 - on (i8.q1 = b2.q1) - on (b2.d2 = b1.q2) - on (t1.f1 = b1.d1) - left join int4_tbl i4 - on (i8.q2 = i4.f1); - f1 -------------------- - doh! - hi de ho neighbor -(2 rows) - -explain (verbose, costs off) -select * from - text_tbl t1 - inner join int8_tbl i8 - on i8.q2 = 456 - right join text_tbl t2 - on t1.f1 = 'doh!' - left join int4_tbl i4 - on i8.q1 = i4.f1; - QUERY PLAN --------------------------------------------------------- - Nested Loop Left Join - Output: t1.f1, i8.q1, i8.q2, t2.f1, i4.f1 - -> Seq Scan on public.text_tbl t2 - Output: t2.f1 - -> Materialize - Output: i8.q1, i8.q2, i4.f1, t1.f1 - -> Nested Loop - Output: i8.q1, i8.q2, i4.f1, t1.f1 - -> Nested Loop Left Join - Output: i8.q1, i8.q2, i4.f1 - Join Filter: (i8.q1 = i4.f1) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - Filter: (i8.q2 = 456) - -> Seq Scan on public.int4_tbl i4 - Output: i4.f1 - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - Filter: (t1.f1 = 'doh!'::text) -(19 rows) - -select * from - text_tbl t1 - inner join int8_tbl i8 - on i8.q2 = 456 - right join text_tbl t2 - on t1.f1 = 'doh!' - left join int4_tbl i4 - on i8.q1 = i4.f1; - f1 | q1 | q2 | f1 | f1 -------+-----+-----+-------------------+---- - doh! | 123 | 456 | doh! | - doh! | 123 | 456 | hi de ho neighbor | -(2 rows) - --- --- test for appropriate join order in the presence of lateral references --- -explain (verbose, costs off) -select * from - text_tbl t1 - left join int8_tbl i8 - on i8.q2 = 123, - lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss -where t1.f1 = ss.f1; - QUERY PLAN --------------------------------------------------- - Nested Loop - Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1 - Join Filter: (t1.f1 = t2.f1) - -> Nested Loop Left Join - Output: t1.f1, i8.q1, i8.q2 - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - -> Materialize - Output: i8.q1, i8.q2 - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - Filter: (i8.q2 = 123) - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 -(16 rows) - -select * from - text_tbl t1 - left join int8_tbl i8 - on i8.q2 = 123, - lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss -where t1.f1 = ss.f1; - f1 | q1 | q2 | q1 | f1 -------+------------------+-----+------------------+------ - doh! | 4567890123456789 | 123 | 4567890123456789 | doh! -(1 row) - -explain (verbose, costs off) -select * from - text_tbl t1 - left join int8_tbl i8 - on i8.q2 = 123, - lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1, - lateral (select ss1.* from text_tbl t3 limit 1) as ss2 -where t1.f1 = ss2.f1; - QUERY PLAN -------------------------------------------------------------------- - Nested Loop - Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1, ((i8.q1)), (t2.f1) - Join Filter: (t1.f1 = (t2.f1)) - -> Nested Loop - Output: t1.f1, i8.q1, i8.q2, (i8.q1), t2.f1 - -> Nested Loop Left Join - Output: t1.f1, i8.q1, i8.q2 - -> Seq Scan on public.text_tbl t1 - Output: t1.f1 - -> Materialize - Output: i8.q1, i8.q2 - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - Filter: (i8.q2 = 123) - -> Limit - Output: (i8.q1), t2.f1 - -> Seq Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 - -> Limit - Output: ((i8.q1)), (t2.f1) - -> Seq Scan on public.text_tbl t3 - Output: (i8.q1), t2.f1 -(22 rows) - -select * from - text_tbl t1 - left join int8_tbl i8 - on i8.q2 = 123, - lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss1, - lateral (select ss1.* from text_tbl t3 limit 1) as ss2 -where t1.f1 = ss2.f1; - f1 | q1 | q2 | q1 | f1 | q1 | f1 -------+------------------+-----+------------------+------+------------------+------ - doh! | 4567890123456789 | 123 | 4567890123456789 | doh! | 4567890123456789 | doh! -(1 row) - -explain (verbose, costs off) -select 1 from - text_tbl as tt1 - inner join text_tbl as tt2 on (tt1.f1 = 'foo') - left join text_tbl as tt3 on (tt3.f1 = 'foo') - left join text_tbl as tt4 on (tt3.f1 = tt4.f1), - lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 -where tt1.f1 = ss1.c0; - QUERY PLAN ----------------------------------------------------------- - Nested Loop - Output: 1 - -> Nested Loop Left Join - Output: tt1.f1, tt4.f1 - -> Nested Loop - Output: tt1.f1 - -> Seq Scan on public.text_tbl tt1 - Output: tt1.f1 - Filter: (tt1.f1 = 'foo'::text) - -> Seq Scan on public.text_tbl tt2 - Output: tt2.f1 - -> Materialize - Output: tt4.f1 - -> Nested Loop Left Join - Output: tt4.f1 - Join Filter: (tt3.f1 = tt4.f1) - -> Seq Scan on public.text_tbl tt3 - Output: tt3.f1 - Filter: (tt3.f1 = 'foo'::text) - -> Seq Scan on public.text_tbl tt4 - Output: tt4.f1 - Filter: (tt4.f1 = 'foo'::text) - -> Subquery Scan on ss1 - Output: ss1.c0 - Filter: (ss1.c0 = 'foo'::text) - -> Limit - Output: (tt4.f1) - -> Seq Scan on public.text_tbl tt5 - Output: tt4.f1 -(29 rows) - -select 1 from - text_tbl as tt1 - inner join text_tbl as tt2 on (tt1.f1 = 'foo') - left join text_tbl as tt3 on (tt3.f1 = 'foo') - left join text_tbl as tt4 on (tt3.f1 = tt4.f1), - lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 -where tt1.f1 = ss1.c0; - ?column? ----------- -(0 rows) - --- --- check a case in which a PlaceHolderVar forces join order --- -explain (verbose, costs off) -select ss2.* from - int4_tbl i41 - left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 - from int4_tbl i42, int4_tbl i43) ss1 - on i8.q1 = ss1.c2 - on i41.f1 = ss1.c1, - lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 -where ss1.c2 = 0; - QUERY PLAN ------------------------------------------------------------------------- - Nested Loop - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Hash Join - Output: i41.f1, i42.f1, i8.q1, i8.q2, i43.f1, 42 - Hash Cond: (i41.f1 = i42.f1) - -> Nested Loop - Output: i8.q1, i8.q2, i43.f1, i41.f1 - -> Nested Loop - Output: i8.q1, i8.q2, i43.f1 - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - Filter: (i8.q1 = 0) - -> Seq Scan on public.int4_tbl i43 - Output: i43.f1 - Filter: (i43.f1 = 0) - -> Seq Scan on public.int4_tbl i41 - Output: i41.f1 - -> Hash - Output: i42.f1 - -> Seq Scan on public.int4_tbl i42 - Output: i42.f1 - -> Limit - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Seq Scan on public.text_tbl - Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) -(25 rows) - -select ss2.* from - int4_tbl i41 - left join int8_tbl i8 - join (select i42.f1 as c1, i43.f1 as c2, 42 as c3 - from int4_tbl i42, int4_tbl i43) ss1 - on i8.q1 = ss1.c2 - on i41.f1 = ss1.c1, - lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 -where ss1.c2 = 0; - f1 | q1 | q2 | c1 | c2 | c3 -----+----+----+----+----+---- -(0 rows) - --- --- test successful handling of full join underneath left join (bug #14105) --- -explain (costs off) -select * from - (select 1 as id) as xx - left join - (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) - on (xx.id = coalesce(yy.id)); - QUERY PLAN ---------------------------------------- - Nested Loop Left Join - -> Result - -> Hash Full Join - Hash Cond: (a1.unique1 = (1)) - Filter: (1 = COALESCE((1))) - -> Seq Scan on tenk1 a1 - -> Hash - -> Result -(8 rows) - -select * from - (select 1 as id) as xx - left join - (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) - on (xx.id = coalesce(yy.id)); - id | unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 | id -----+---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------+---- - 1 | 1 | 2838 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 3 | BAAAAA | EFEAAA | OOOOxx | 1 -(1 row) - --- --- test ability to push constants through outer join clauses --- -explain (costs off) - select * from int4_tbl a left join tenk1 b on f1 = unique2 where f1 = 0; - QUERY PLAN -------------------------------------------------- - Nested Loop Left Join - Join Filter: (a.f1 = b.unique2) - -> Seq Scan on int4_tbl a - Filter: (f1 = 0) - -> Index Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 = 0) -(6 rows) - -explain (costs off) - select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42; - QUERY PLAN -------------------------------------------------- - Merge Full Join - Merge Cond: (a.unique2 = b.unique2) - -> Index Scan using tenk1_unique2 on tenk1 a - Index Cond: (unique2 = 42) - -> Index Scan using tenk1_unique2 on tenk1 b - Index Cond: (unique2 = 42) -(6 rows) - --- --- test that quals attached to an outer join have correct semantics, --- specifically that they don't re-use expressions computed below the join; --- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input --- -set enable_hashjoin to off; -set enable_nestloop to off; -explain (verbose, costs off) - select a.q2, b.q1 - from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) - where coalesce(b.q1, 1) > 0; - QUERY PLAN ---------------------------------------------------------- - Merge Left Join - Output: a.q2, b.q1 - Merge Cond: (a.q2 = (COALESCE(b.q1, '1'::bigint))) - Filter: (COALESCE(b.q1, '1'::bigint) > 0) - -> Sort - Output: a.q2 - Sort Key: a.q2 - -> Seq Scan on public.int8_tbl a - Output: a.q2 - -> Sort - Output: b.q1, (COALESCE(b.q1, '1'::bigint)) - Sort Key: (COALESCE(b.q1, '1'::bigint)) - -> Seq Scan on public.int8_tbl b - Output: b.q1, COALESCE(b.q1, '1'::bigint) -(14 rows) - -select a.q2, b.q1 - from int8_tbl a left join int8_tbl b on a.q2 = coalesce(b.q1, 1) - where coalesce(b.q1, 1) > 0; - q2 | q1 --------------------+------------------ - -4567890123456789 | - 123 | 123 - 123 | 123 - 456 | - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 -(10 rows) - -reset enable_hashjoin; -reset enable_nestloop; --- --- test join removal --- -begin; -CREATE TEMP TABLE a (id int PRIMARY KEY, b_id int); -CREATE TEMP TABLE b (id int PRIMARY KEY, c_id int); -CREATE TEMP TABLE c (id int PRIMARY KEY); -CREATE TEMP TABLE d (a int, b int); -INSERT INTO a VALUES (0, 0), (1, NULL); -INSERT INTO b VALUES (0, 0), (1, NULL); -INSERT INTO c VALUES (0), (1); -INSERT INTO d VALUES (1,3), (2,2), (3,1); --- all three cases should be optimizable into a simple seqscan -explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; - QUERY PLAN ---------------- - Seq Scan on a -(1 row) - -explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; - QUERY PLAN ---------------- - Seq Scan on b -(1 row) - -explain (costs off) - SELECT a.* FROM a LEFT JOIN (b left join c on b.c_id = c.id) - ON (a.b_id = b.id); - QUERY PLAN ---------------- - Seq Scan on a -(1 row) - --- check optimization of outer join within another special join -explain (costs off) -select id from a where id in ( - select b.id from b left join c on b.id = c.id -); - QUERY PLAN ----------------------------- - Hash Join - Hash Cond: (a.id = b.id) - -> Seq Scan on a - -> Hash - -> Seq Scan on b -(5 rows) - --- check that join removal works for a left join when joining a subquery --- that is guaranteed to be unique by its GROUP BY clause -explain (costs off) -select d.* from d left join (select * from b group by b.id, b.c_id) s - on d.a = s.id and d.b = s.c_id; - QUERY PLAN ---------------- - Seq Scan on d -(1 row) - --- similarly, but keying off a DISTINCT clause -explain (costs off) -select d.* from d left join (select distinct * from b) s - on d.a = s.id and d.b = s.c_id; - QUERY PLAN ---------------- - Seq Scan on d -(1 row) - --- join removal is not possible when the GROUP BY contains a column that is --- not in the join condition. (Note: as of 9.6, we notice that b.id is a --- primary key and so drop b.c_id from the GROUP BY of the resulting plan; --- but this happens too late for join removal in the outer plan level.) -explain (costs off) -select d.* from d left join (select * from b group by b.id, b.c_id) s - on d.a = s.id; - QUERY PLAN ------------------------------------------- - Merge Right Join - Merge Cond: (b.id = d.a) - -> Group - Group Key: b.id - -> Index Scan using b_pkey on b - -> Sort - Sort Key: d.a - -> Seq Scan on d -(8 rows) - --- similarly, but keying off a DISTINCT clause -explain (costs off) -select d.* from d left join (select distinct * from b) s - on d.a = s.id; - QUERY PLAN --------------------------------------- - Merge Right Join - Merge Cond: (b.id = d.a) - -> Unique - -> Sort - Sort Key: b.id, b.c_id - -> Seq Scan on b - -> Sort - Sort Key: d.a - -> Seq Scan on d -(9 rows) - --- check join removal works when uniqueness of the join condition is enforced --- by a UNION -explain (costs off) -select d.* from d left join (select id from a union select id from b) s - on d.a = s.id; - QUERY PLAN ---------------- - Seq Scan on d -(1 row) - --- check join removal with a cross-type comparison operator -explain (costs off) -select i8.* from int8_tbl i8 left join (select f1 from int4_tbl group by f1) i4 - on i8.q1 = i4.f1; - QUERY PLAN -------------------------- - Seq Scan on int8_tbl i8 -(1 row) - --- check join removal with lateral references -explain (costs off) -select 1 from (select a.id FROM a left join b on a.b_id = b.id) q, - lateral generate_series(1, q.id) gs(i) where q.id = gs.i; - QUERY PLAN -------------------------------------------- - Nested Loop - -> Seq Scan on a - -> Function Scan on generate_series gs - Filter: (a.id = i) -(4 rows) - -rollback; -create temp table parent (k int primary key, pd int); -create temp table child (k int unique, cd int); -insert into parent values (1, 10), (2, 20), (3, 30); -insert into child values (1, 100), (4, 400); --- this case is optimizable -select p.* from parent p left join child c on (p.k = c.k); - k | pd ----+---- - 1 | 10 - 2 | 20 - 3 | 30 -(3 rows) - -explain (costs off) - select p.* from parent p left join child c on (p.k = c.k); - QUERY PLAN ----------------------- - Seq Scan on parent p -(1 row) - --- this case is not -select p.*, linked from parent p - left join (select c.*, true as linked from child c) as ss - on (p.k = ss.k); - k | pd | linked ----+----+-------- - 1 | 10 | t - 2 | 20 | - 3 | 30 | -(3 rows) - -explain (costs off) - select p.*, linked from parent p - left join (select c.*, true as linked from child c) as ss - on (p.k = ss.k); - QUERY PLAN ---------------------------------- - Hash Left Join - Hash Cond: (p.k = c.k) - -> Seq Scan on parent p - -> Hash - -> Seq Scan on child c -(5 rows) - --- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling -select p.* from - parent p left join child c on (p.k = c.k) - where p.k = 1 and p.k = 2; - k | pd ----+---- -(0 rows) - -explain (costs off) -select p.* from - parent p left join child c on (p.k = c.k) - where p.k = 1 and p.k = 2; - QUERY PLAN ------------------------------------------------- - Result - One-Time Filter: false - -> Index Scan using parent_pkey on parent p - Index Cond: (k = 1) -(4 rows) - -select p.* from - (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k - where p.k = 1 and p.k = 2; - k | pd ----+---- -(0 rows) - -explain (costs off) -select p.* from - (parent p left join child c on (p.k = c.k)) join parent x on p.k = x.k - where p.k = 1 and p.k = 2; - QUERY PLAN --------------------------- - Result - One-Time Filter: false -(2 rows) - --- bug 5255: this is not optimizable by join removal -begin; -CREATE TEMP TABLE a (id int PRIMARY KEY); -CREATE TEMP TABLE b (id int PRIMARY KEY, a_id int); -INSERT INTO a VALUES (0), (1); -INSERT INTO b VALUES (0, 0), (1, NULL); -SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); - id | a_id | id -----+------+---- - 1 | | -(1 row) - -SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); - id | a_id -----+------ - 1 | -(1 row) - -rollback; --- another join removal bug: this is not optimizable, either -begin; -create temp table innertab (id int8 primary key, dat1 int8); -insert into innertab values(123, 42); -SELECT * FROM - (SELECT 1 AS x) ss1 - LEFT JOIN - (SELECT q1, q2, COALESCE(dat1, q1) AS y - FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss2 - ON true; - x | q1 | q2 | y ----+------------------+-------------------+------------------ - 1 | 123 | 456 | 123 - 1 | 123 | 4567890123456789 | 123 - 1 | 4567890123456789 | 123 | 42 - 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 1 | 4567890123456789 | -4567890123456789 | 4567890123456789 -(5 rows) - -rollback; --- another join removal bug: we must clean up correctly when removing a PHV -begin; -create temp table uniquetbl (f1 text unique); -explain (costs off) -select t1.* from - uniquetbl as t1 - left join (select *, '***'::text as d1 from uniquetbl) t2 - on t1.f1 = t2.f1 - left join uniquetbl t3 - on t2.d1 = t3.f1; - QUERY PLAN --------------------------- - Seq Scan on uniquetbl t1 -(1 row) - -explain (costs off) -select t0.* -from - text_tbl t0 - left join - (select case t1.ten when 0 then 'doh!'::text else null::text end as case1, - t1.stringu2 - from tenk1 t1 - join int4_tbl i4 ON i4.f1 = t1.unique2 - left join uniquetbl u1 ON u1.f1 = t1.string4) ss - on t0.f1 = ss.case1 -where ss.stringu2 !~* ss.case1; - QUERY PLAN --------------------------------------------------------------------------------------------- - Nested Loop - Join Filter: (CASE t1.ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END = t0.f1) - -> Nested Loop - -> Seq Scan on int4_tbl i4 - -> Index Scan using tenk1_unique2 on tenk1 t1 - Index Cond: (unique2 = i4.f1) - Filter: (stringu2 !~* CASE ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END) - -> Materialize - -> Seq Scan on text_tbl t0 -(9 rows) - -select t0.* -from - text_tbl t0 - left join - (select case t1.ten when 0 then 'doh!'::text else null::text end as case1, - t1.stringu2 - from tenk1 t1 - join int4_tbl i4 ON i4.f1 = t1.unique2 - left join uniquetbl u1 ON u1.f1 = t1.string4) ss - on t0.f1 = ss.case1 -where ss.stringu2 !~* ss.case1; - f1 ------- - doh! -(1 row) - -rollback; --- test case to expose miscomputation of required relid set for a PHV -explain (verbose, costs off) -select i8.*, ss.v, t.unique2 - from int8_tbl i8 - left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true - left join tenk1 t on t.unique2 = ss.v -where q2 = 456; - QUERY PLAN -------------------------------------------------------------- - Nested Loop Left Join - Output: i8.q1, i8.q2, ((i4.f1 + 1)), t.unique2 - -> Nested Loop Left Join - Output: i8.q1, i8.q2, (i4.f1 + 1) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - Filter: (i8.q2 = 456) - -> Seq Scan on public.int4_tbl i4 - Output: i4.f1 - Filter: (i4.f1 = 1) - -> Index Only Scan using tenk1_unique2 on public.tenk1 t - Output: t.unique2 - Index Cond: (t.unique2 = ((i4.f1 + 1))) -(13 rows) - -select i8.*, ss.v, t.unique2 - from int8_tbl i8 - left join int4_tbl i4 on i4.f1 = 1 - left join lateral (select i4.f1 + 1 as v) as ss on true - left join tenk1 t on t.unique2 = ss.v -where q2 = 456; - q1 | q2 | v | unique2 ------+-----+---+--------- - 123 | 456 | | -(1 row) - --- and check a related issue where we miscompute required relids for --- a PHV that's been translated to a child rel -create temp table parttbl (a integer primary key) partition by range (a); -create temp table parttbl1 partition of parttbl for values from (1) to (100); -insert into parttbl values (11), (12); -explain (costs off) -select * from - (select *, 12 as phv from parttbl) as ss - right join int4_tbl on true -where ss.a = ss.phv and f1 = 0; - QUERY PLAN ------------------------------------- - Nested Loop - -> Seq Scan on int4_tbl - Filter: (f1 = 0) - -> Seq Scan on parttbl1 parttbl - Filter: (a = 12) -(5 rows) - -select * from - (select *, 12 as phv from parttbl) as ss - right join int4_tbl on true -where ss.a = ss.phv and f1 = 0; - a | phv | f1 -----+-----+---- - 12 | 12 | 0 -(1 row) - --- bug #8444: we've historically allowed duplicate aliases within aliased JOINs -select * from - int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; -- error -ERROR: column reference "f1" is ambiguous -LINE 2: ..._tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; - ^ -select * from - int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; -- error -ERROR: invalid reference to FROM-clause entry for table "y" -LINE 2: ...bl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; - ^ -HINT: There is an entry for table "y", but it cannot be referenced from this part of the query. -select * from - int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1; -- ok - q1 | q2 | f1 | ff -----+----+----+---- -(0 rows) - --- --- Test hints given on incorrect column references are useful --- -select t1.uunique1 from - tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t1" suggestion -ERROR: column t1.uunique1 does not exist -LINE 1: select t1.uunique1 from - ^ -HINT: Perhaps you meant to reference the column "t1.unique1". -select t2.uunique1 from - tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t2" suggestion -ERROR: column t2.uunique1 does not exist -LINE 1: select t2.uunique1 from - ^ -HINT: Perhaps you meant to reference the column "t2.unique1". -select uunique1 from - tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, suggest both at once -ERROR: column "uunique1" does not exist -LINE 1: select uunique1 from - ^ -HINT: Perhaps you meant to reference the column "t1.unique1" or the column "t2.unique1". --- --- Take care to reference the correct RTE --- -select atts.relid::regclass, s.* from pg_stats s join - pg_attribute a on s.attname = a.attname and s.tablename = - a.attrelid::regclass::text join (select unnest(indkey) attnum, - indexrelid from pg_index i) atts on atts.attnum = a.attnum where - schemaname != 'pg_catalog'; -ERROR: column atts.relid does not exist -LINE 1: select atts.relid::regclass, s.* from pg_stats s join - ^ --- --- Test LATERAL --- -select unique2, x.* -from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; - unique2 | f1 ----------+---- - 9998 | 0 -(1 row) - -explain (costs off) - select unique2, x.* - from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; - QUERY PLAN -------------------------------------------------- - Nested Loop - -> Seq Scan on int4_tbl b - -> Index Scan using tenk1_unique1 on tenk1 a - Index Cond: (unique1 = b.f1) -(4 rows) - -select unique2, x.* -from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; - unique2 | f1 ----------+---- - 9998 | 0 -(1 row) - -explain (costs off) - select unique2, x.* - from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; - QUERY PLAN ------------------------------------------------ - Nested Loop - -> Seq Scan on int4_tbl x - -> Index Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = x.f1) -(4 rows) - -explain (costs off) - select unique2, x.* - from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss; - QUERY PLAN ------------------------------------------------ - Nested Loop - -> Seq Scan on int4_tbl x - -> Index Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = x.f1) -(4 rows) - -select unique2, x.* -from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; - unique2 | f1 ----------+------------- - 9998 | 0 - | 123456 - | -123456 - | 2147483647 - | -2147483647 -(5 rows) - -explain (costs off) - select unique2, x.* - from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; - QUERY PLAN ------------------------------------------------ - Nested Loop Left Join - -> Seq Scan on int4_tbl x - -> Index Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = x.f1) -(4 rows) - --- check scoping of lateral versus parent references --- the first of these should return int8_tbl.q2, the second int8_tbl.q1 -select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; - q1 | q2 | r -------------------+-------------------+------------------- - 123 | 456 | 456 - 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | -4567890123456789 -(5 rows) - -select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; - q1 | q2 | r -------------------+-------------------+------------------ - 123 | 456 | 123 - 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 -(5 rows) - --- lateral with function in FROM -select count(*) from tenk1 a, lateral generate_series(1,two) g; - count -------- - 5000 -(1 row) - -explain (costs off) - select count(*) from tenk1 a, lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------- - Aggregate - -> Nested Loop - -> Seq Scan on tenk1 a - -> Function Scan on generate_series g -(4 rows) - -explain (costs off) - select count(*) from tenk1 a cross join lateral generate_series(1,two) g; - QUERY PLAN ------------------------------------------------- - Aggregate - -> Nested Loop - -> Seq Scan on tenk1 a - -> Function Scan on generate_series g -(4 rows) - --- don't need the explicit LATERAL keyword for functions -explain (costs off) - select count(*) from tenk1 a, generate_series(1,two) g; - QUERY PLAN ------------------------------------------------- - Aggregate - -> Nested Loop - -> Seq Scan on tenk1 a - -> Function Scan on generate_series g -(4 rows) - --- lateral with UNION ALL subselect -explain (costs off) - select * from generate_series(100,200) g, - lateral (select * from int8_tbl a where g = q1 union all - select * from int8_tbl b where g = q2) ss; - QUERY PLAN ------------------------------------------- - Nested Loop - -> Function Scan on generate_series g - -> Append - -> Seq Scan on int8_tbl a - Filter: (g.g = q1) - -> Seq Scan on int8_tbl b - Filter: (g.g = q2) -(7 rows) - -select * from generate_series(100,200) g, - lateral (select * from int8_tbl a where g = q1 union all - select * from int8_tbl b where g = q2) ss; - g | q1 | q2 ------+------------------+------------------ - 123 | 123 | 456 - 123 | 123 | 4567890123456789 - 123 | 4567890123456789 | 123 -(3 rows) - --- lateral with VALUES -explain (costs off) - select count(*) from tenk1 a, - tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Merge Join - Merge Cond: (a.unique1 = b.unique2) - -> Index Only Scan using tenk1_unique1 on tenk1 a - -> Index Only Scan using tenk1_unique2 on tenk1 b -(5 rows) - -select count(*) from tenk1 a, - tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; - count -------- - 10000 -(1 row) - --- lateral with VALUES, no flattening possible -explain (costs off) - select count(*) from tenk1 a, - tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; - QUERY PLAN ------------------------------------------------------------------- - Aggregate - -> Hash Join - Hash Cond: ("*VALUES*".column1 = b.unique2) - -> Nested Loop - -> Index Only Scan using tenk1_unique1 on tenk1 a - -> Values Scan on "*VALUES*" - -> Hash - -> Index Only Scan using tenk1_unique2 on tenk1 b -(8 rows) - -select count(*) from tenk1 a, - tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; - count -------- - 10000 -(1 row) - --- lateral injecting a strange outer join condition -explain (costs off) - select * from int8_tbl a, - int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) - on x.q2 = ss.z - order by a.q1, a.q2, x.q1, x.q2, ss.z; - QUERY PLAN ------------------------------------------------- - Sort - Sort Key: a.q1, a.q2, x.q1, x.q2, (a.q1) - -> Nested Loop - -> Seq Scan on int8_tbl a - -> Hash Right Join - Hash Cond: ((a.q1) = x.q2) - -> Seq Scan on int4_tbl y - -> Hash - -> Seq Scan on int8_tbl x -(9 rows) - -select * from int8_tbl a, - int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) - on x.q2 = ss.z - order by a.q1, a.q2, x.q1, x.q2, ss.z; - q1 | q2 | q1 | q2 | z -------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | 123 | 456 | - 123 | 456 | 123 | 4567890123456789 | - 123 | 456 | 4567890123456789 | -4567890123456789 | - 123 | 456 | 4567890123456789 | 123 | 123 - 123 | 456 | 4567890123456789 | 123 | 123 - 123 | 456 | 4567890123456789 | 123 | 123 - 123 | 456 | 4567890123456789 | 123 | 123 - 123 | 456 | 4567890123456789 | 123 | 123 - 123 | 456 | 4567890123456789 | 4567890123456789 | - 123 | 4567890123456789 | 123 | 456 | - 123 | 4567890123456789 | 123 | 4567890123456789 | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | - 4567890123456789 | -4567890123456789 | 123 | 456 | - 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 | -4567890123456789 | - 4567890123456789 | -4567890123456789 | 4567890123456789 | 123 | - 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 4567890123456789 | -4567890123456789 | - 4567890123456789 | 123 | 4567890123456789 | 123 | - 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 123 | 456 | - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 -(57 rows) - --- lateral reference to a join alias variable -select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, - lateral (select x) ss2(y); - x | f1 | y ----+----+--- - 0 | 0 | 0 -(1 row) - -select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, - lateral (values(x)) ss2(y); - x | f1 | y --------------+-------------+------------- - 0 | 0 | 0 - 123456 | 123456 | 123456 - -123456 | -123456 | -123456 - 2147483647 | 2147483647 | 2147483647 - -2147483647 | -2147483647 | -2147483647 -(5 rows) - -select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, - lateral (select x) ss2(y); - x | f1 | y ----+----+--- - 0 | 0 | 0 -(1 row) - --- lateral references requiring pullup -select * from (values(1)) x(lb), - lateral generate_series(lb,4) x4; - lb | x4 -----+---- - 1 | 1 - 1 | 2 - 1 | 3 - 1 | 4 -(4 rows) - -select * from (select f1/1000000000 from int4_tbl) x(lb), - lateral generate_series(lb,4) x4; - lb | x4 -----+---- - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 0 - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 2 | 2 - 2 | 3 - 2 | 4 - -2 | -2 - -2 | -1 - -2 | 0 - -2 | 1 - -2 | 2 - -2 | 3 - -2 | 4 -(25 rows) - -select * from (values(1)) x(lb), - lateral (values(lb)) y(lbcopy); - lb | lbcopy -----+-------- - 1 | 1 -(1 row) - -select * from (values(1)) x(lb), - lateral (select lb from int4_tbl) y(lbcopy); - lb | lbcopy -----+-------- - 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 - 1 | 1 -(5 rows) - -select * from - int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, - lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2); - q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 -------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 123 | 456 | | | 123 | | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | -(10 rows) - -select * from - int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, - lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); - q1 | q2 | q1 | q2 | xq1 | yq1 | yq2 -------------------+-------------------+------------------+-------------------+------------------+------------------+------------------- - 123 | 456 | | | 123 | | - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 123 | 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 4567890123456789 | 123 | 456 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | -(10 rows) - -select x.* from - int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1, - lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2); - q1 | q2 -------------------+------------------- - 123 | 456 - 123 | 4567890123456789 - 123 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 -(10 rows) - -select v.* from - (int8_tbl x left join (select q1,coalesce(q2,0) q2 from int8_tbl) y on x.q2 = y.q1) - left join int4_tbl z on z.f1 = x.q2, - lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); - vx | vy --------------------+------------------- - 123 | - 456 | - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | - -4567890123456789 | -(20 rows) - -select v.* from - (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) - left join int4_tbl z on z.f1 = x.q2, - lateral (select x.q1,y.q1 union all select x.q2,y.q2) v(vx,vy); - vx | vy --------------------+------------------- - 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | - 456 | - 4567890123456789 | - -4567890123456789 | -(20 rows) - -select v.* from - (int8_tbl x left join (select q1,(select coalesce(q2,0)) q2 from int8_tbl) y on x.q2 = y.q1) - left join int4_tbl z on z.f1 = x.q2, - lateral (select x.q1,y.q1 from onerow union all select x.q2,y.q2 from onerow) v(vx,vy); - vx | vy --------------------+------------------- - 4567890123456789 | 123 - 123 | 456 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 123 - 123 | 4567890123456789 - 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | 4567890123456789 - 4567890123456789 | -4567890123456789 - 123 | - 456 | - 4567890123456789 | - -4567890123456789 | -(20 rows) - -explain (verbose, costs off) -select * from - int8_tbl a left join - lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; - QUERY PLAN ------------------------------------------- - Nested Loop Left Join - Output: a.q1, a.q2, b.q1, b.q2, (a.q2) - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 - -> Seq Scan on public.int8_tbl b - Output: b.q1, b.q2, a.q2 - Filter: (a.q2 = b.q1) -(7 rows) - -select * from - int8_tbl a left join - lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; - q1 | q2 | q1 | q2 | x -------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | | | -(10 rows) - -explain (verbose, costs off) -select * from - int8_tbl a left join - lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; - QUERY PLAN ------------------------------------------------------------------- - Nested Loop Left Join - Output: a.q1, a.q2, b.q1, b.q2, (COALESCE(a.q2, '42'::bigint)) - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 - -> Seq Scan on public.int8_tbl b - Output: b.q1, b.q2, COALESCE(a.q2, '42'::bigint) - Filter: (a.q2 = b.q1) -(7 rows) - -select * from - int8_tbl a left join - lateral (select *, coalesce(a.q2, 42) as x from int8_tbl b) ss on a.q2 = ss.q1; - q1 | q2 | q1 | q2 | x -------------------+-------------------+------------------+-------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 123 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | 123 | 123 | 456 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | | | -(10 rows) - --- lateral can result in join conditions appearing below their --- real semantic level -explain (verbose, costs off) -select * from int4_tbl i left join - lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; - QUERY PLAN -------------------------------------------- - Hash Left Join - Output: i.f1, j.f1 - Hash Cond: (i.f1 = j.f1) - -> Seq Scan on public.int4_tbl i - Output: i.f1 - -> Hash - Output: j.f1 - -> Seq Scan on public.int2_tbl j - Output: j.f1 -(9 rows) - -select * from int4_tbl i left join - lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; - f1 | f1 --------------+---- - 0 | 0 - 123456 | - -123456 | - 2147483647 | - -2147483647 | -(5 rows) - -explain (verbose, costs off) -select * from int4_tbl i left join - lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; - QUERY PLAN -------------------------------------- - Nested Loop Left Join - Output: i.f1, (COALESCE(i.*)) - -> Seq Scan on public.int4_tbl i - Output: i.f1, i.* - -> Seq Scan on public.int2_tbl j - Output: j.f1, COALESCE(i.*) - Filter: (i.f1 = j.f1) -(7 rows) - -select * from int4_tbl i left join - lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; - f1 | coalesce --------------+---------- - 0 | (0) - 123456 | - -123456 | - 2147483647 | - -2147483647 | -(5 rows) - -explain (verbose, costs off) -select * from int4_tbl a, - lateral ( - select * from int4_tbl b left join int8_tbl c on (b.f1 = q1 and a.f1 = q2) - ) ss; - QUERY PLAN -------------------------------------------------- - Nested Loop - Output: a.f1, b.f1, c.q1, c.q2 - -> Seq Scan on public.int4_tbl a - Output: a.f1 - -> Hash Left Join - Output: b.f1, c.q1, c.q2 - Hash Cond: (b.f1 = c.q1) - -> Seq Scan on public.int4_tbl b - Output: b.f1 - -> Hash - Output: c.q1, c.q2 - -> Seq Scan on public.int8_tbl c - Output: c.q1, c.q2 - Filter: (a.f1 = c.q2) -(14 rows) - -select * from int4_tbl a, - lateral ( - select * from int4_tbl b left join int8_tbl c on (b.f1 = q1 and a.f1 = q2) - ) ss; - f1 | f1 | q1 | q2 --------------+-------------+----+---- - 0 | 0 | | - 0 | 123456 | | - 0 | -123456 | | - 0 | 2147483647 | | - 0 | -2147483647 | | - 123456 | 0 | | - 123456 | 123456 | | - 123456 | -123456 | | - 123456 | 2147483647 | | - 123456 | -2147483647 | | - -123456 | 0 | | - -123456 | 123456 | | - -123456 | -123456 | | - -123456 | 2147483647 | | - -123456 | -2147483647 | | - 2147483647 | 0 | | - 2147483647 | 123456 | | - 2147483647 | -123456 | | - 2147483647 | 2147483647 | | - 2147483647 | -2147483647 | | - -2147483647 | 0 | | - -2147483647 | 123456 | | - -2147483647 | -123456 | | - -2147483647 | 2147483647 | | - -2147483647 | -2147483647 | | -(25 rows) - --- lateral reference in a PlaceHolderVar evaluated at join level -explain (verbose, costs off) -select * from - int8_tbl a left join lateral - (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from - int8_tbl b cross join int8_tbl c) ss - on a.q2 = ss.bq1; - QUERY PLAN -------------------------------------------------------------- - Nested Loop Left Join - Output: a.q1, a.q2, b.q1, c.q1, (LEAST(a.q1, b.q1, c.q1)) - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 - -> Nested Loop - Output: b.q1, c.q1, LEAST(a.q1, b.q1, c.q1) - -> Seq Scan on public.int8_tbl b - Output: b.q1, b.q2 - Filter: (a.q2 = b.q1) - -> Seq Scan on public.int8_tbl c - Output: c.q1, c.q2 -(11 rows) - -select * from - int8_tbl a left join lateral - (select b.q1 as bq1, c.q1 as cq1, least(a.q1,b.q1,c.q1) from - int8_tbl b cross join int8_tbl c) ss - on a.q2 = ss.bq1; - q1 | q2 | bq1 | cq1 | least -------------------+-------------------+------------------+------------------+------------------ - 123 | 456 | | | - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 123 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 123 | 123 - 4567890123456789 | 123 | 123 | 123 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 123 | 123 - 4567890123456789 | 123 | 123 | 123 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 123 | 123 | 4567890123456789 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 123 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 4567890123456789 | -4567890123456789 | | | -(42 rows) - --- case requiring nested PlaceHolderVars -explain (verbose, costs off) -select * from - int8_tbl c left join ( - int8_tbl a left join (select q1, coalesce(q2,42) as x from int8_tbl b) ss1 - on a.q2 = ss1.q1 - cross join - lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 - ) on c.q2 = ss2.q1, - lateral (select ss2.y offset 0) ss3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Nested Loop - Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)), ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) - -> Hash Right Join - Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) - Hash Cond: (d.q1 = c.q2) - -> Nested Loop - Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) - -> Hash Left Join - Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)) - Hash Cond: (a.q2 = b.q1) - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 - -> Hash - Output: b.q1, (COALESCE(b.q2, '42'::bigint)) - -> Seq Scan on public.int8_tbl b - Output: b.q1, COALESCE(b.q2, '42'::bigint) - -> Seq Scan on public.int8_tbl d - Output: d.q1, COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2) - -> Hash - Output: c.q1, c.q2 - -> Seq Scan on public.int8_tbl c - Output: c.q1, c.q2 - -> Result - Output: (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) -(24 rows) - --- case that breaks the old ph_may_need optimization -explain (verbose, costs off) -select c.*,a.*,ss1.q1,ss2.q1,ss3.* from - int8_tbl c left join ( - int8_tbl a left join - (select q1, coalesce(q2,f1) as x from int8_tbl b, int4_tbl b2 - where q1 < f1) ss1 - on a.q2 = ss1.q1 - cross join - lateral (select q1, coalesce(ss1.x,q2) as y from int8_tbl d) ss2 - ) on c.q2 = ss2.q1, - lateral (select * from int4_tbl i where ss2.y > f1) ss3; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Nested Loop - Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, i.f1 - Join Filter: ((COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) > i.f1) - -> Hash Right Join - Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) - Hash Cond: (d.q1 = c.q2) - -> Nested Loop - Output: a.q1, a.q2, b.q1, d.q1, (COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2)) - -> Hash Right Join - Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, (b2.f1)::bigint)) - Hash Cond: (b.q1 = a.q2) - -> Nested Loop - Output: b.q1, COALESCE(b.q2, (b2.f1)::bigint) - Join Filter: (b.q1 < b2.f1) - -> Seq Scan on public.int8_tbl b - Output: b.q1, b.q2 - -> Materialize - Output: b2.f1 - -> Seq Scan on public.int4_tbl b2 - Output: b2.f1 - -> Hash - Output: a.q1, a.q2 - -> Seq Scan on public.int8_tbl a - Output: a.q1, a.q2 - -> Seq Scan on public.int8_tbl d - Output: d.q1, COALESCE((COALESCE(b.q2, (b2.f1)::bigint)), d.q2) - -> Hash - Output: c.q1, c.q2 - -> Seq Scan on public.int8_tbl c - Output: c.q1, c.q2 - -> Materialize - Output: i.f1 - -> Seq Scan on public.int4_tbl i - Output: i.f1 -(34 rows) - --- check processing of postponed quals (bug #9041) -explain (verbose, costs off) -select * from - (select 1 as x offset 0) x cross join (select 2 as y offset 0) y - left join lateral ( - select * from (select 3 as z offset 0) z where z.z = x.x - ) zz on zz.z = y.y; - QUERY PLAN ----------------------------------------------- - Nested Loop Left Join - Output: (1), (2), (3) - Join Filter: (((3) = (1)) AND ((3) = (2))) - -> Nested Loop - Output: (1), (2) - -> Result - Output: 1 - -> Result - Output: 2 - -> Result - Output: 3 -(11 rows) - --- check dummy rels with lateral references (bug #15694) -explain (verbose, costs off) -select * from int8_tbl i8 left join lateral - (select *, i8.q2 from int4_tbl where false) ss on true; - QUERY PLAN --------------------------------------- - Nested Loop Left Join - Output: i8.q1, i8.q2, f1, (i8.q2) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Result - Output: f1, i8.q2 - One-Time Filter: false -(7 rows) - -explain (verbose, costs off) -select * from int8_tbl i8 left join lateral - (select *, i8.q2 from int4_tbl i1, int4_tbl i2 where false) ss on true; - QUERY PLAN ------------------------------------------ - Nested Loop Left Join - Output: i8.q1, i8.q2, f1, f1, (i8.q2) - -> Seq Scan on public.int8_tbl i8 - Output: i8.q1, i8.q2 - -> Result - Output: f1, f1, i8.q2 - One-Time Filter: false -(7 rows) - --- check handling of nested appendrels inside LATERAL -select * from - ((select 2 as v) union all (select 3 as v)) as q1 - cross join lateral - ((select * from - ((select 4 as v) union all (select 5 as v)) as q3) - union all - (select q1.v) - ) as q2; - v | v ----+--- - 2 | 4 - 2 | 5 - 2 | 2 - 3 | 4 - 3 | 5 - 3 | 3 -(6 rows) - --- check we don't try to do a unique-ified semijoin with LATERAL -explain (verbose, costs off) -select * from - (values (0,9998), (1,1000)) v(id,x), - lateral (select f1 from int4_tbl - where f1 = any (select unique1 from tenk1 - where unique2 = v.x offset 0)) ss; - QUERY PLAN ----------------------------------------------------------------------- - Nested Loop - Output: "*VALUES*".column1, "*VALUES*".column2, int4_tbl.f1 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1, "*VALUES*".column2 - -> Nested Loop Semi Join - Output: int4_tbl.f1 - Join Filter: (int4_tbl.f1 = tenk1.unique1) - -> Seq Scan on public.int4_tbl - Output: int4_tbl.f1 - -> Materialize - Output: tenk1.unique1 - -> Index Scan using tenk1_unique2 on public.tenk1 - Output: tenk1.unique1 - Index Cond: (tenk1.unique2 = "*VALUES*".column2) -(14 rows) - -select * from - (values (0,9998), (1,1000)) v(id,x), - lateral (select f1 from int4_tbl - where f1 = any (select unique1 from tenk1 - where unique2 = v.x offset 0)) ss; - id | x | f1 -----+------+---- - 0 | 9998 | 0 -(1 row) - --- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, --- but we can make the test case much more compact with LATERAL) -explain (verbose, costs off) -select * from (values (0), (1)) v(id), -lateral (select * from int8_tbl t1, - lateral (select * from - (select * from int8_tbl t2 - where q1 = any (select q2 from int8_tbl t3 - where q2 = (select greatest(t1.q1,t2.q2)) - and (select v.id=0)) offset 0) ss2) ss - where t1.q1 = ss.q2) ss0; - QUERY PLAN ------------------------------------------------------------------ - Nested Loop - Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2 - -> Seq Scan on public.int8_tbl t1 - Output: t1.q1, t1.q2 - -> Nested Loop - Output: "*VALUES*".column1, ss2.q1, ss2.q2 - -> Values Scan on "*VALUES*" - Output: "*VALUES*".column1 - -> Subquery Scan on ss2 - Output: ss2.q1, ss2.q2 - Filter: (t1.q1 = ss2.q2) - -> Seq Scan on public.int8_tbl t2 - Output: t2.q1, t2.q2 - Filter: (SubPlan 3) - SubPlan 3 - -> Result - Output: t3.q2 - One-Time Filter: $4 - InitPlan 1 (returns $2) - -> Result - Output: GREATEST($0, t2.q2) - InitPlan 2 (returns $4) - -> Result - Output: ($3 = 0) - -> Seq Scan on public.int8_tbl t3 - Output: t3.q1, t3.q2 - Filter: (t3.q2 = $2) -(27 rows) - -select * from (values (0), (1)) v(id), -lateral (select * from int8_tbl t1, - lateral (select * from - (select * from int8_tbl t2 - where q1 = any (select q2 from int8_tbl t3 - where q2 = (select greatest(t1.q1,t2.q2)) - and (select v.id=0)) offset 0) ss2) ss - where t1.q1 = ss.q2) ss0; - id | q1 | q2 | q1 | q2 -----+------------------+-------------------+------------------+------------------ - 0 | 4567890123456789 | 123 | 4567890123456789 | 4567890123456789 - 0 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 - 0 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 -(3 rows) - --- test some error cases where LATERAL should have been used but wasn't -select f1,g from int4_tbl a, (select f1 as g) ss; -ERROR: column "f1" does not exist -LINE 1: select f1,g from int4_tbl a, (select f1 as g) ss; - ^ -HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. -select f1,g from int4_tbl a, (select a.f1 as g) ss; -ERROR: invalid reference to FROM-clause entry for table "a" -LINE 1: select f1,g from int4_tbl a, (select a.f1 as g) ss; - ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. -select f1,g from int4_tbl a cross join (select f1 as g) ss; -ERROR: column "f1" does not exist -LINE 1: select f1,g from int4_tbl a cross join (select f1 as g) ss; - ^ -HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. -select f1,g from int4_tbl a cross join (select a.f1 as g) ss; -ERROR: invalid reference to FROM-clause entry for table "a" -LINE 1: select f1,g from int4_tbl a cross join (select a.f1 as g) ss... - ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. --- SQL:2008 says the left table is in scope but illegal to access here -select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true; -ERROR: invalid reference to FROM-clause entry for table "a" -LINE 1: ... int4_tbl a right join lateral generate_series(0, a.f1) g on... - ^ -DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. -select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true; -ERROR: invalid reference to FROM-clause entry for table "a" -LINE 1: ...m int4_tbl a full join lateral generate_series(0, a.f1) g on... - ^ -DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. --- check we complain about ambiguous table references -select * from - int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss); -ERROR: table reference "x" is ambiguous -LINE 2: ...cross join (int4_tbl x cross join lateral (select x.f1) ss); - ^ --- LATERAL can be used to put an aggregate into the FROM clause of its query -select 1 from tenk1 a, lateral (select max(a.unique1) from int4_tbl b) ss; -ERROR: aggregate functions are not allowed in FROM clause of their own query level -LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... - ^ --- check behavior of LATERAL in UPDATE/DELETE -create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; --- error, can't do this: -update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; -ERROR: column "x1" does not exist -LINE 1: ... set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; - ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. -update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss; -ERROR: invalid reference to FROM-clause entry for table "xx1" -LINE 1: ...t x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss... - ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. --- can't do it even with LATERAL: -update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss; -ERROR: invalid reference to FROM-clause entry for table "xx1" -LINE 1: ...= f1 from lateral (select * from int4_tbl where f1 = x1) ss; - ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. --- we might in future allow something like this, but for now it's an error: -update xx1 set x2 = f1 from xx1, lateral (select * from int4_tbl where f1 = x1) ss; -ERROR: table name "xx1" specified more than once --- also errors: -delete from xx1 using (select * from int4_tbl where f1 = x1) ss; -ERROR: column "x1" does not exist -LINE 1: ...te from xx1 using (select * from int4_tbl where f1 = x1) ss; - ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. -delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss; -ERROR: invalid reference to FROM-clause entry for table "xx1" -LINE 1: ...from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss... - ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. -delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss; -ERROR: invalid reference to FROM-clause entry for table "xx1" -LINE 1: ...xx1 using lateral (select * from int4_tbl where f1 = x1) ss; - ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. --- --- test LATERAL reference propagation down a multi-level inheritance hierarchy --- produced for a multi-level partitioned table hierarchy. --- -create table join_pt1 (a int, b int, c varchar) partition by range(a); -create table join_pt1p1 partition of join_pt1 for values from (0) to (100) partition by range(b); -create table join_pt1p2 partition of join_pt1 for values from (100) to (200); -create table join_pt1p1p1 partition of join_pt1p1 for values from (0) to (100); -insert into join_pt1 values (1, 1, 'x'), (101, 101, 'y'); -create table join_ut1 (a int, b int, c varchar); -insert into join_ut1 values (101, 101, 'y'), (2, 2, 'z'); -explain (verbose, costs off) -select t1.b, ss.phv from join_ut1 t1 left join lateral - (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv - from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss - on t1.a = ss.t2a order by t1.a; - QUERY PLAN --------------------------------------------------------------------- - Sort - Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a - Sort Key: t1.a - -> Nested Loop Left Join - Output: t1.b, (LEAST(t1.a, t2.a, t3.a)), t1.a - -> Seq Scan on public.join_ut1 t1 - Output: t1.a, t1.b, t1.c - -> Hash Join - Output: t2.a, LEAST(t1.a, t2.a, t3.a) - Hash Cond: (t3.b = t2.a) - -> Seq Scan on public.join_ut1 t3 - Output: t3.a, t3.b, t3.c - -> Hash - Output: t2.a - -> Append - -> Seq Scan on public.join_pt1p1p1 t2_1 - Output: t2_1.a - Filter: (t1.a = t2_1.a) - -> Seq Scan on public.join_pt1p2 t2_2 - Output: t2_2.a - Filter: (t1.a = t2_2.a) -(21 rows) - -select t1.b, ss.phv from join_ut1 t1 left join lateral - (select t2.a as t2a, t3.a t3a, least(t1.a, t2.a, t3.a) phv - from join_pt1 t2 join join_ut1 t3 on t2.a = t3.b) ss - on t1.a = ss.t2a order by t1.a; - b | phv ------+----- - 2 | - 101 | 101 -(2 rows) - -drop table join_pt1; -drop table join_ut1; --- --- test that foreign key join estimation performs sanely for outer joins --- -begin; -create table fkest (a int, b int, c int unique, primary key(a,b)); -create table fkest1 (a int, b int, primary key(a,b)); -insert into fkest select x/10, x%10, x from generate_series(1,1000) x; -insert into fkest1 select x/10, x%10 from generate_series(1,1000) x; -alter table fkest1 - add constraint fkest1_a_b_fkey foreign key (a,b) references fkest; -analyze fkest; -analyze fkest1; -explain (costs off) -select * -from fkest f - left join fkest1 f1 on f.a = f1.a and f.b = f1.b - left join fkest1 f2 on f.a = f2.a and f.b = f2.b - left join fkest1 f3 on f.a = f3.a and f.b = f3.b -where f.c = 1; - QUERY PLAN ------------------------------------------------------------------- - Nested Loop Left Join - -> Nested Loop Left Join - -> Nested Loop Left Join - -> Index Scan using fkest_c_key on fkest f - Index Cond: (c = 1) - -> Index Only Scan using fkest1_pkey on fkest1 f1 - Index Cond: ((a = f.a) AND (b = f.b)) - -> Index Only Scan using fkest1_pkey on fkest1 f2 - Index Cond: ((a = f.a) AND (b = f.b)) - -> Index Only Scan using fkest1_pkey on fkest1 f3 - Index Cond: ((a = f.a) AND (b = f.b)) -(11 rows) - -rollback; --- --- test planner's ability to mark joins as unique --- -create table j1 (id int primary key); -create table j2 (id int primary key); -create table j3 (id int); -insert into j1 values(1),(2),(3); -insert into j2 values(1),(2),(3); -insert into j3 values(1),(1); -analyze j1; -analyze j2; -analyze j3; --- ensure join is properly marked as unique -explain (verbose, costs off) -select * from j1 inner join j2 on j1.id = j2.id; - QUERY PLAN ------------------------------------ - Hash Join - Output: j1.id, j2.id - Inner Unique: true - Hash Cond: (j1.id = j2.id) - -> Seq Scan on public.j1 - Output: j1.id - -> Hash - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(10 rows) - --- ensure join is not unique when not an equi-join -explain (verbose, costs off) -select * from j1 inner join j2 on j1.id > j2.id; - QUERY PLAN ------------------------------------ - Nested Loop - Output: j1.id, j2.id - Join Filter: (j1.id > j2.id) - -> Seq Scan on public.j1 - Output: j1.id - -> Materialize - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(9 rows) - --- ensure non-unique rel is not chosen as inner -explain (verbose, costs off) -select * from j1 inner join j3 on j1.id = j3.id; - QUERY PLAN ------------------------------------ - Hash Join - Output: j1.id, j3.id - Inner Unique: true - Hash Cond: (j3.id = j1.id) - -> Seq Scan on public.j3 - Output: j3.id - -> Hash - Output: j1.id - -> Seq Scan on public.j1 - Output: j1.id -(10 rows) - --- ensure left join is marked as unique -explain (verbose, costs off) -select * from j1 left join j2 on j1.id = j2.id; - QUERY PLAN ------------------------------------ - Hash Left Join - Output: j1.id, j2.id - Inner Unique: true - Hash Cond: (j1.id = j2.id) - -> Seq Scan on public.j1 - Output: j1.id - -> Hash - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(10 rows) - --- ensure right join is marked as unique -explain (verbose, costs off) -select * from j1 right join j2 on j1.id = j2.id; - QUERY PLAN ------------------------------------ - Hash Left Join - Output: j1.id, j2.id - Inner Unique: true - Hash Cond: (j2.id = j1.id) - -> Seq Scan on public.j2 - Output: j2.id - -> Hash - Output: j1.id - -> Seq Scan on public.j1 - Output: j1.id -(10 rows) - --- ensure full join is marked as unique -explain (verbose, costs off) -select * from j1 full join j2 on j1.id = j2.id; - QUERY PLAN ------------------------------------ - Hash Full Join - Output: j1.id, j2.id - Inner Unique: true - Hash Cond: (j1.id = j2.id) - -> Seq Scan on public.j1 - Output: j1.id - -> Hash - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(10 rows) - --- a clauseless (cross) join can't be unique -explain (verbose, costs off) -select * from j1 cross join j2; - QUERY PLAN ------------------------------------ - Nested Loop - Output: j1.id, j2.id - -> Seq Scan on public.j1 - Output: j1.id - -> Materialize - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(8 rows) - --- ensure a natural join is marked as unique -explain (verbose, costs off) -select * from j1 natural join j2; - QUERY PLAN ------------------------------------ - Hash Join - Output: j1.id - Inner Unique: true - Hash Cond: (j1.id = j2.id) - -> Seq Scan on public.j1 - Output: j1.id - -> Hash - Output: j2.id - -> Seq Scan on public.j2 - Output: j2.id -(10 rows) - --- ensure a distinct clause allows the inner to become unique -explain (verbose, costs off) -select * from j1 -inner join (select distinct id from j3) j3 on j1.id = j3.id; - QUERY PLAN ------------------------------------------ - Nested Loop - Output: j1.id, j3.id - Inner Unique: true - Join Filter: (j1.id = j3.id) - -> Unique - Output: j3.id - -> Sort - Output: j3.id - Sort Key: j3.id - -> Seq Scan on public.j3 - Output: j3.id - -> Seq Scan on public.j1 - Output: j1.id -(13 rows) - --- ensure group by clause allows the inner to become unique -explain (verbose, costs off) -select * from j1 -inner join (select id from j3 group by id) j3 on j1.id = j3.id; - QUERY PLAN ------------------------------------------ - Nested Loop - Output: j1.id, j3.id - Inner Unique: true - Join Filter: (j1.id = j3.id) - -> Group - Output: j3.id - Group Key: j3.id - -> Sort - Output: j3.id - Sort Key: j3.id - -> Seq Scan on public.j3 - Output: j3.id - -> Seq Scan on public.j1 - Output: j1.id -(14 rows) - -drop table j1; -drop table j2; -drop table j3; --- test more complex permutations of unique joins -create table j1 (id1 int, id2 int, primary key(id1,id2)); -create table j2 (id1 int, id2 int, primary key(id1,id2)); -create table j3 (id1 int, id2 int, primary key(id1,id2)); -insert into j1 values(1,1),(1,2); -insert into j2 values(1,1); -insert into j3 values(1,1); -analyze j1; -analyze j2; -analyze j3; --- ensure there's no unique join when not all columns which are part of the --- unique index are seen in the join clause -explain (verbose, costs off) -select * from j1 -inner join j2 on j1.id1 = j2.id1; - QUERY PLAN ------------------------------------------- - Nested Loop - Output: j1.id1, j1.id2, j2.id1, j2.id2 - Join Filter: (j1.id1 = j2.id1) - -> Seq Scan on public.j2 - Output: j2.id1, j2.id2 - -> Seq Scan on public.j1 - Output: j1.id1, j1.id2 -(7 rows) - --- ensure proper unique detection with multiple join quals -explain (verbose, costs off) -select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; - QUERY PLAN ----------------------------------------------------------- - Nested Loop - Output: j1.id1, j1.id2, j2.id1, j2.id2 - Inner Unique: true - Join Filter: ((j1.id1 = j2.id1) AND (j1.id2 = j2.id2)) - -> Seq Scan on public.j2 - Output: j2.id1, j2.id2 - -> Seq Scan on public.j1 - Output: j1.id1, j1.id2 -(8 rows) - --- ensure we don't detect the join to be unique when quals are not part of the --- join condition -explain (verbose, costs off) -select * from j1 -inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; - QUERY PLAN ------------------------------------------- - Nested Loop - Output: j1.id1, j1.id2, j2.id1, j2.id2 - Join Filter: (j1.id1 = j2.id1) - -> Seq Scan on public.j1 - Output: j1.id1, j1.id2 - Filter: (j1.id2 = 1) - -> Seq Scan on public.j2 - Output: j2.id1, j2.id2 -(8 rows) - --- as above, but for left joins. -explain (verbose, costs off) -select * from j1 -left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; - QUERY PLAN ------------------------------------------- - Nested Loop Left Join - Output: j1.id1, j1.id2, j2.id1, j2.id2 - Join Filter: (j1.id1 = j2.id1) - -> Seq Scan on public.j1 - Output: j1.id1, j1.id2 - Filter: (j1.id2 = 1) - -> Seq Scan on public.j2 - Output: j2.id1, j2.id2 -(8 rows) - --- validate logic in merge joins which skips mark and restore. --- it should only do this if all quals which were used to detect the unique --- are present as join quals, and not plain quals. -set enable_nestloop to 0; -set enable_hashjoin to 0; -set enable_sort to 0; --- create indexes that will be preferred over the PKs to perform the join -create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; -create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; --- need an additional row in j2, if we want j2_id1_idx to be preferred -insert into j2 values(1,2); -analyze j2; -explain (costs off) select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; - QUERY PLAN ------------------------------------------ - Merge Join - Merge Cond: (j1.id1 = j2.id1) - Join Filter: (j1.id2 = j2.id2) - -> Index Scan using j1_id1_idx on j1 - -> Index Scan using j2_id1_idx on j2 -(5 rows) - -select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; - id1 | id2 | id1 | id2 ------+-----+-----+----- - 1 | 1 | 1 | 1 - 1 | 2 | 1 | 2 -(2 rows) - --- Exercise array keys mark/restore B-Tree code -explain (costs off) select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); - QUERY PLAN ----------------------------------------------------- - Merge Join - Merge Cond: (j1.id1 = j2.id1) - Join Filter: (j1.id2 = j2.id2) - -> Index Scan using j1_id1_idx on j1 - -> Index Scan using j2_id1_idx on j2 - Index Cond: (id1 = ANY ('{1}'::integer[])) -(6 rows) - -select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); - id1 | id2 | id1 | id2 ------+-----+-----+----- - 1 | 1 | 1 | 1 - 1 | 2 | 1 | 2 -(2 rows) - --- Exercise array keys "find extreme element" B-Tree code -explain (costs off) select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); - QUERY PLAN -------------------------------------------------------- - Merge Join - Merge Cond: (j1.id1 = j2.id1) - Join Filter: (j1.id2 = j2.id2) - -> Index Scan using j1_id1_idx on j1 - -> Index Only Scan using j2_pkey on j2 - Index Cond: (id1 >= ANY ('{1,5}'::integer[])) - Filter: ((id1 % 1000) = 1) -(7 rows) - -select * from j1 -inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 -where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); - id1 | id2 | id1 | id2 ------+-----+-----+----- - 1 | 1 | 1 | 1 - 1 | 2 | 1 | 2 -(2 rows) - -reset enable_nestloop; -reset enable_hashjoin; -reset enable_sort; -drop table j1; -drop table j2; -drop table j3; --- check that semijoin inner is not seen as unique for a portion of the outerrel -explain (verbose, costs off) -select t1.unique1, t2.hundred -from onek t1, tenk1 t2 -where exists (select 1 from tenk1 t3 - where t3.thousand = t1.unique1 and t3.tenthous = t2.hundred) - and t1.unique1 < 1; - QUERY PLAN ---------------------------------------------------------------------------------- - Nested Loop - Output: t1.unique1, t2.hundred - -> Hash Join - Output: t1.unique1, t3.tenthous - Hash Cond: (t3.thousand = t1.unique1) - -> HashAggregate - Output: t3.thousand, t3.tenthous - Group Key: t3.thousand, t3.tenthous - -> Index Only Scan using tenk1_thous_tenthous on public.tenk1 t3 - Output: t3.thousand, t3.tenthous - -> Hash - Output: t1.unique1 - -> Index Only Scan using onek_unique1 on public.onek t1 - Output: t1.unique1 - Index Cond: (t1.unique1 < 1) - -> Index Only Scan using tenk1_hundred on public.tenk1 t2 - Output: t2.hundred - Index Cond: (t2.hundred = t3.tenthous) -(18 rows) - --- ... unless it actually is unique -create table j3 as select unique1, tenthous from onek; -vacuum analyze j3; -create unique index on j3(unique1, tenthous); -explain (verbose, costs off) -select t1.unique1, t2.hundred -from onek t1, tenk1 t2 -where exists (select 1 from j3 - where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) - and t1.unique1 < 1; - QUERY PLAN ------------------------------------------------------------------------- - Nested Loop - Output: t1.unique1, t2.hundred - -> Nested Loop - Output: t1.unique1, j3.tenthous - -> Index Only Scan using onek_unique1 on public.onek t1 - Output: t1.unique1 - Index Cond: (t1.unique1 < 1) - -> Index Only Scan using j3_unique1_tenthous_idx on public.j3 - Output: j3.unique1, j3.tenthous - Index Cond: (j3.unique1 = t1.unique1) - -> Index Only Scan using tenk1_hundred on public.tenk1 t2 - Output: t2.hundred - Index Cond: (t2.hundred = j3.tenthous) -(13 rows) - -drop table j3; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/aggregates.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/aggregates.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/aggregates.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/aggregates.out 2022-02-13 01:12:13.548833037 +0100 @@ -2577,176 +2577,8 @@ group by unique1 having sum(fivethous) > 4975 order by sum(twothousand); - unique1 | count | sum ----------+-------+------ - 4976 | 1 | 976 - 4977 | 1 | 977 - 4978 | 1 | 978 - 4979 | 1 | 979 - 4980 | 1 | 980 - 4981 | 1 | 981 - 4982 | 1 | 982 - 4983 | 1 | 983 - 4984 | 1 | 984 - 4985 | 1 | 985 - 4986 | 1 | 986 - 4987 | 1 | 987 - 4988 | 1 | 988 - 4989 | 1 | 989 - 4990 | 1 | 990 - 4991 | 1 | 991 - 4992 | 1 | 992 - 4993 | 1 | 993 - 4994 | 1 | 994 - 4995 | 1 | 995 - 4996 | 1 | 996 - 4997 | 1 | 997 - 4998 | 1 | 998 - 4999 | 1 | 999 - 9976 | 1 | 1976 - 9977 | 1 | 1977 - 9978 | 1 | 1978 - 9979 | 1 | 1979 - 9980 | 1 | 1980 - 9981 | 1 | 1981 - 9982 | 1 | 1982 - 9983 | 1 | 1983 - 9984 | 1 | 1984 - 9985 | 1 | 1985 - 9986 | 1 | 1986 - 9987 | 1 | 1987 - 9988 | 1 | 1988 - 9989 | 1 | 1989 - 9990 | 1 | 1990 - 9991 | 1 | 1991 - 9992 | 1 | 1992 - 9993 | 1 | 1993 - 9994 | 1 | 1994 - 9995 | 1 | 1995 - 9996 | 1 | 1996 - 9997 | 1 | 1997 - 9998 | 1 | 1998 - 9999 | 1 | 1999 -(48 rows) - -set work_mem to default; -set enable_sort to default; --- --- Compare results between plans using sorting and plans using hash --- aggregation. Force spilling in both cases by setting work_mem low. --- -set work_mem='64kB'; -create table agg_data_2k as -select g from generate_series(0, 1999) g; -analyze agg_data_2k; -create table agg_data_20k as -select g from generate_series(0, 19999) g; -analyze agg_data_20k; --- Produce results with sorting. -set enable_hashagg = false; -set jit_above_cost = 0; -explain (costs off) -select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 - from agg_data_20k group by g%10000; - QUERY PLAN --------------------------------------- - GroupAggregate - Group Key: ((g % 10000)) - -> Sort - Sort Key: ((g % 10000)) - -> Seq Scan on agg_data_20k -(5 rows) - -create table agg_group_1 as -select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 - from agg_data_20k group by g%10000; -create table agg_group_2 as -select * from - (values (100), (300), (500)) as r(a), - lateral ( - select (g/2)::numeric as c1, - array_agg(g::numeric) as c2, - count(*) as c3 - from agg_data_2k - where g < r.a - group by g/2) as s; -set jit_above_cost to default; -create table agg_group_3 as -select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 - from agg_data_2k group by g/2; -create table agg_group_4 as -select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 - from agg_data_2k group by g/2; --- Produce results with hash aggregation -set enable_hashagg = true; -set enable_sort = false; -set jit_above_cost = 0; -explain (costs off) -select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 - from agg_data_20k group by g%10000; - QUERY PLAN --------------------------------- - HashAggregate - Group Key: (g % 10000) - -> Seq Scan on agg_data_20k -(3 rows) - -create table agg_hash_1 as -select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 - from agg_data_20k group by g%10000; -create table agg_hash_2 as -select * from - (values (100), (300), (500)) as r(a), - lateral ( - select (g/2)::numeric as c1, - array_agg(g::numeric) as c2, - count(*) as c3 - from agg_data_2k - where g < r.a - group by g/2) as s; -set jit_above_cost to default; -create table agg_hash_3 as -select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 - from agg_data_2k group by g/2; -create table agg_hash_4 as -select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 - from agg_data_2k group by g/2; -set enable_sort = true; -set work_mem to default; --- Compare group aggregation results to hash aggregation results -(select * from agg_hash_1 except select * from agg_group_1) - union all -(select * from agg_group_1 except select * from agg_hash_1); - c1 | c2 | c3 -----+----+---- -(0 rows) - -(select * from agg_hash_2 except select * from agg_group_2) - union all -(select * from agg_group_2 except select * from agg_hash_2); - a | c1 | c2 | c3 ----+----+----+---- -(0 rows) - -(select * from agg_hash_3 except select * from agg_group_3) - union all -(select * from agg_group_3 except select * from agg_hash_3); - c1 | c2 | c3 -----+----+---- -(0 rows) - -(select * from agg_hash_4 except select * from agg_group_4) - union all -(select * from agg_group_4 except select * from agg_hash_4); - c1 | c2 | c3 -----+----+---- -(0 rows) - -drop table agg_group_1; -drop table agg_group_2; -drop table agg_group_3; -drop table agg_group_4; -drop table agg_hash_1; -drop table agg_hash_2; -drop table agg_hash_3; -drop table agg_hash_4; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/btree_index.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/btree_index.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/btree_index.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/btree_index.out 2022-02-13 01:12:12.842165178 +0100 @@ -189,155 +189,8 @@ explain (costs off) select proname from pg_proc where proname ilike 'ri%foo' order by 1; - QUERY PLAN ------------------------------------------------------------------ - Index Only Scan using pg_proc_proname_args_nsp_index on pg_proc - Filter: (proname ~~* 'ri%foo'::text) -(2 rows) - -reset enable_seqscan; -reset enable_indexscan; -reset enable_bitmapscan; --- Also check LIKE optimization with binary-compatible cases -create temp table btree_bpchar (f1 text collate "C"); -create index on btree_bpchar(f1 bpchar_ops) WITH (deduplicate_items=on); -insert into btree_bpchar values ('foo'), ('fool'), ('bar'), ('quux'); --- doesn't match index: -explain (costs off) -select * from btree_bpchar where f1 like 'foo'; - QUERY PLAN -------------------------------- - Seq Scan on btree_bpchar - Filter: (f1 ~~ 'foo'::text) -(2 rows) - -select * from btree_bpchar where f1 like 'foo'; - f1 ------ - foo -(1 row) - -explain (costs off) -select * from btree_bpchar where f1 like 'foo%'; - QUERY PLAN --------------------------------- - Seq Scan on btree_bpchar - Filter: (f1 ~~ 'foo%'::text) -(2 rows) - -select * from btree_bpchar where f1 like 'foo%'; - f1 ------- - foo - fool -(2 rows) - --- these do match the index: -explain (costs off) -select * from btree_bpchar where f1::bpchar like 'foo'; - QUERY PLAN ----------------------------------------------------- - Bitmap Heap Scan on btree_bpchar - Filter: ((f1)::bpchar ~~ 'foo'::text) - -> Bitmap Index Scan on btree_bpchar_f1_idx - Index Cond: ((f1)::bpchar = 'foo'::bpchar) -(4 rows) - -select * from btree_bpchar where f1::bpchar like 'foo'; - f1 ------ - foo -(1 row) - -explain (costs off) -select * from btree_bpchar where f1::bpchar like 'foo%'; - QUERY PLAN ------------------------------------------------------------------------------------------- - Bitmap Heap Scan on btree_bpchar - Filter: ((f1)::bpchar ~~ 'foo%'::text) - -> Bitmap Index Scan on btree_bpchar_f1_idx - Index Cond: (((f1)::bpchar >= 'foo'::bpchar) AND ((f1)::bpchar < 'fop'::bpchar)) -(4 rows) - -select * from btree_bpchar where f1::bpchar like 'foo%'; - f1 ------- - foo - fool -(2 rows) - --- get test coverage for "single value" deduplication strategy: -insert into btree_bpchar select 'foo' from generate_series(1,1500); --- --- Perform unique checking, with and without the use of deduplication --- -CREATE TABLE dedup_unique_test_table (a int) WITH (autovacuum_enabled=false); -CREATE UNIQUE INDEX dedup_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=on); -CREATE UNIQUE INDEX plain_unique ON dedup_unique_test_table (a) WITH (deduplicate_items=off); --- Generate enough garbage tuples in index to ensure that even the unique index --- with deduplication enabled has to check multiple leaf pages during unique --- checking (at least with a BLCKSZ of 8192 or less) -DO $$ -BEGIN - FOR r IN 1..1350 LOOP - DELETE FROM dedup_unique_test_table; - INSERT INTO dedup_unique_test_table SELECT 1; - END LOOP; -END$$; --- Exercise the LP_DEAD-bit-set tuple deletion code with a posting list tuple. --- The implementation prefers deleting existing items to merging any duplicate --- tuples into a posting list, so we need an explicit test to make sure we get --- coverage (note that this test also assumes BLCKSZ is 8192 or less): -DROP INDEX plain_unique; -DELETE FROM dedup_unique_test_table WHERE a = 1; -INSERT INTO dedup_unique_test_table SELECT i FROM generate_series(0,450) i; --- --- Test B-tree fast path (cache rightmost leaf page) optimization. --- --- First create a tree that's at least three levels deep (i.e. has one level --- between the root and leaf levels). The text inserted is long. It won't be --- TOAST compressed because we use plain storage in the table. Only a few --- index tuples fit on each internal page, allowing us to get a tall tree with --- few pages. (A tall tree is required to trigger caching.) --- --- The text column must be the leading column in the index, since suffix --- truncation would otherwise truncate tuples on internal pages, leaving us --- with a short tree. -create table btree_tall_tbl(id int4, t text); -alter table btree_tall_tbl alter COLUMN t set storage plain; -create index btree_tall_idx on btree_tall_tbl (t, id) with (fillfactor = 10); -insert into btree_tall_tbl select g, repeat('x', 250) -from generate_series(1, 130) g; --- --- Test for multilevel page deletion --- -CREATE TABLE delete_test_table (a bigint, b bigint, c bigint, d bigint); -INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,80000) i; -ALTER TABLE delete_test_table ADD PRIMARY KEY (a,b,c,d); --- Delete most entries, and vacuum, deleting internal pages and creating "fast --- root" -DELETE FROM delete_test_table WHERE a < 79990; -VACUUM delete_test_table; --- --- Test B-tree insertion with a metapage update (XLOG_BTREE_INSERT_META --- WAL record type). This happens when a "fast root" page is split. This --- also creates coverage for nbtree FSM page recycling. --- --- The vacuum above should've turned the leaf page into a fast root. We just --- need to insert some rows to cause the fast root page to split. -INSERT INTO delete_test_table SELECT i, 1, 2, 3 FROM generate_series(1,1000) i; --- Test unsupported btree opclass parameters -create index on btree_tall_tbl (id int4_ops(foo=1)); -ERROR: operator class int4_ops has no options --- Test case of ALTER INDEX with abuse of column names for indexes. --- This grammar is not officially supported, but the parser allows it. -CREATE INDEX btree_tall_idx2 ON btree_tall_tbl (id); -ALTER INDEX btree_tall_idx2 ALTER COLUMN id SET (n_distinct=100); -ERROR: "btree_tall_idx2" is not a table, materialized view, or foreign table -DROP INDEX btree_tall_idx2; --- Partitioned index -CREATE TABLE btree_part (id int4) PARTITION BY RANGE (id); -CREATE INDEX btree_part_idx ON btree_part(id); -ALTER INDEX btree_part_idx ALTER COLUMN id SET (n_distinct=100); -ERROR: "btree_part_idx" is not a table, materialized view, or foreign table -DROP TABLE btree_part; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/update.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/update.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/update.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/update.out 2022-02-13 01:12:12.942165347 +0100 @@ -433,635 +433,8 @@ CREATE VIEW upview AS SELECT * FROM range_parted WHERE (select c > c1 FROM mintab) WITH CHECK OPTION; -- ok UPDATE upview set c = 199 WHERE b = 4; --- fail, check option violation -UPDATE upview set c = 120 WHERE b = 4; -ERROR: new row violates check option for view "upview" -DETAIL: Failing row contains (a, 4, 120, 1, 1). --- fail, row movement with check option violation -UPDATE upview set a = 'b', b = 15, c = 120 WHERE b = 4; -ERROR: new row violates check option for view "upview" -DETAIL: Failing row contains (b, 15, 120, 1, 1). --- ok, row movement, check option passes -UPDATE upview set a = 'b', b = 15 WHERE b = 4; -:show_data; - partname | a | b | c | d | e ----------------+---+----+-----+---+--- - part_a_1_a_10 | a | 1 | 1 | 1 | 1 - part_b_1_b_10 | b | 7 | 117 | 2 | 2 - part_b_1_b_10 | b | 9 | 125 | 6 | 6 - part_d_1_15 | b | 11 | 125 | 9 | 9 - part_d_1_15 | b | 12 | 116 | 1 | 1 - part_d_1_15 | b | 15 | 199 | 1 | 1 -(6 rows) - --- cleanup -DROP VIEW upview; --- RETURNING having whole-row vars. -:init_range_parted; -UPDATE range_parted set c = 95 WHERE a = 'b' and b > 10 and c > 100 returning (range_parted), *; - range_parted | a | b | c | d | e ----------------+---+----+----+----+--- - (b,15,95,16,) | b | 15 | 95 | 16 | - (b,17,95,19,) | b | 17 | 95 | 19 | -(2 rows) - -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 12 | 96 | 1 | - part_c_1_100 | b | 13 | 97 | 2 | - part_c_1_100 | b | 15 | 95 | 16 | - part_c_1_100 | b | 17 | 95 | 19 | -(6 rows) - --- The following tests computing RETURNING when the source and the destination --- partitions of a UPDATE row movement operation have different tuple --- descriptors, which has been shown to be problematic in the cases where the --- RETURNING targetlist contains non-target relation attributes that are --- computed by referring to the source partition plan's output tuple. Also, --- a trigger on the destination relation may change the tuple, which must be --- reflected in the RETURNING output, so we test that too. -CREATE TABLE part_c_1_c_20 (LIKE range_parted); -ALTER TABLE part_c_1_c_20 DROP a, DROP b, ADD a text, ADD b bigint; -ALTER TABLE range_parted ATTACH PARTITION part_c_1_c_20 FOR VALUES FROM ('c', 1) TO ('c', 20); -CREATE FUNCTION trigfunc () RETURNS TRIGGER LANGUAGE plpgsql as $$ BEGIN NEW.e := 'in trigfunc()'; RETURN NEW; END; $$; -CREATE TRIGGER trig BEFORE INSERT ON part_c_1_c_20 FOR EACH ROW EXECUTE FUNCTION trigfunc(); -UPDATE range_parted r set a = 'c' FROM (VALUES ('a', 1), ('a', 10), ('b', 12)) s(x, y) WHERE s.x = r.a AND s.y = r.b RETURNING tableoid::regclass, *; - tableoid | a | b | c | d | e | x | y ----------------+---+----+-----+---+---------------+---+---- - part_c_1_c_20 | c | 1 | 1 | 1 | in trigfunc() | a | 1 - part_c_1_c_20 | c | 10 | 200 | 1 | in trigfunc() | a | 10 - part_c_1_c_20 | c | 12 | 96 | 1 | in trigfunc() | b | 12 -(3 rows) - -DROP TRIGGER trig ON part_c_1_c_20; -DROP FUNCTION trigfunc; -:init_range_parted; -CREATE FUNCTION trigfunc () RETURNS TRIGGER LANGUAGE plpgsql as $$ BEGIN RETURN NULL; END; $$; -CREATE TRIGGER trig BEFORE INSERT ON part_c_1_c_20 FOR EACH ROW EXECUTE FUNCTION trigfunc(); -UPDATE range_parted r set a = 'c' FROM (VALUES ('a', 1), ('a', 10), ('b', 12)) s(x, y) WHERE s.x = r.a AND s.y = r.b RETURNING tableoid::regclass, *; - tableoid | a | b | c | d | e | x | y -----------+---+---+---+---+---+---+--- -(0 rows) - -:show_data; - partname | a | b | c | d | e ---------------+---+----+-----+----+--- - part_c_1_100 | b | 13 | 97 | 2 | - part_d_15_20 | b | 15 | 105 | 16 | - part_d_15_20 | b | 17 | 105 | 19 | -(3 rows) - -DROP TABLE part_c_1_c_20; -DROP FUNCTION trigfunc; --- Transition tables with update row movement -:init_range_parted; -CREATE FUNCTION trans_updatetrigfunc() RETURNS trigger LANGUAGE plpgsql AS -$$ - begin - raise notice 'trigger = %, old table = %, new table = %', - TG_NAME, - (select string_agg(old_table::text, ', ' ORDER BY a) FROM old_table), - (select string_agg(new_table::text, ', ' ORDER BY a) FROM new_table); - return null; - end; -$$; -CREATE TRIGGER trans_updatetrig - AFTER UPDATE ON range_parted REFERENCING OLD TABLE AS old_table NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); -UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end ) WHERE a = 'b' and b > 10 and c >= 96; -NOTICE: trigger = trans_updatetrig, old table = (b,12,96,1,), (b,13,97,2,), (b,15,105,16,), (b,17,105,19,), new table = (b,12,110,1,), (b,13,98,2,), (b,15,106,16,), (b,17,106,19,) -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 13 | 98 | 2 | - part_d_15_20 | b | 15 | 106 | 16 | - part_d_15_20 | b | 17 | 106 | 19 | - part_d_1_15 | b | 12 | 110 | 1 | -(6 rows) - -:init_range_parted; --- Enabling OLD TABLE capture for both DELETE as well as UPDATE stmt triggers --- should not cause DELETEd rows to be captured twice. Similar thing for --- INSERT triggers and inserted rows. -CREATE TRIGGER trans_deletetrig - AFTER DELETE ON range_parted REFERENCING OLD TABLE AS old_table - FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); -CREATE TRIGGER trans_inserttrig - AFTER INSERT ON range_parted REFERENCING NEW TABLE AS new_table - FOR EACH STATEMENT EXECUTE PROCEDURE trans_updatetrigfunc(); -UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96; -NOTICE: trigger = trans_updatetrig, old table = (b,12,96,1,), (b,13,97,2,), (b,15,105,16,), (b,17,105,19,), new table = (b,12,146,1,), (b,13,147,2,), (b,15,155,16,), (b,17,155,19,) -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_d_15_20 | b | 15 | 155 | 16 | - part_d_15_20 | b | 17 | 155 | 19 | - part_d_1_15 | b | 12 | 146 | 1 | - part_d_1_15 | b | 13 | 147 | 2 | -(6 rows) - -DROP TRIGGER trans_deletetrig ON range_parted; -DROP TRIGGER trans_inserttrig ON range_parted; --- Don't drop trans_updatetrig yet. It is required below. --- Test with transition tuple conversion happening for rows moved into the --- new partition. This requires a trigger that references transition table --- (we already have trans_updatetrig). For inserted rows, the conversion --- is not usually needed, because the original tuple is already compatible with --- the desired transition tuple format. But conversion happens when there is a --- BR trigger because the trigger can change the inserted row. So install a --- BR triggers on those child partitions where the rows will be moved. -CREATE FUNCTION func_parted_mod_b() RETURNS trigger AS $$ -BEGIN - NEW.b = NEW.b + 1; - return NEW; -END $$ language plpgsql; -CREATE TRIGGER trig_c1_100 BEFORE UPDATE OR INSERT ON part_c_1_100 - FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); -CREATE TRIGGER trig_d1_15 BEFORE UPDATE OR INSERT ON part_d_1_15 - FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); -CREATE TRIGGER trig_d15_20 BEFORE UPDATE OR INSERT ON part_d_15_20 - FOR EACH ROW EXECUTE PROCEDURE func_parted_mod_b(); -:init_range_parted; -UPDATE range_parted set c = (case when c = 96 then 110 else c + 1 end) WHERE a = 'b' and b > 10 and c >= 96; -NOTICE: trigger = trans_updatetrig, old table = (b,13,96,1,), (b,14,97,2,), (b,16,105,16,), (b,18,105,19,), new table = (b,15,110,1,), (b,15,98,2,), (b,17,106,16,), (b,19,106,19,) -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 15 | 98 | 2 | - part_d_15_20 | b | 17 | 106 | 16 | - part_d_15_20 | b | 19 | 106 | 19 | - part_d_1_15 | b | 15 | 110 | 1 | -(6 rows) - -:init_range_parted; -UPDATE range_parted set c = c + 50 WHERE a = 'b' and b > 10 and c >= 96; -NOTICE: trigger = trans_updatetrig, old table = (b,13,96,1,), (b,14,97,2,), (b,16,105,16,), (b,18,105,19,), new table = (b,15,146,1,), (b,16,147,2,), (b,17,155,16,), (b,19,155,19,) -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_d_15_20 | b | 17 | 155 | 16 | - part_d_15_20 | b | 19 | 155 | 19 | - part_d_1_15 | b | 15 | 146 | 1 | - part_d_1_15 | b | 16 | 147 | 2 | -(6 rows) - --- Case where per-partition tuple conversion map array is allocated, but the --- map is not required for the particular tuple that is routed, thanks to --- matching table attributes of the partition and the target table. -:init_range_parted; -UPDATE range_parted set b = 15 WHERE b = 1; -NOTICE: trigger = trans_updatetrig, old table = (a,1,1,1,), new table = (a,15,1,1,) -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_10_a_20 | a | 15 | 1 | 1 | - part_c_1_100 | b | 13 | 96 | 1 | - part_c_1_100 | b | 14 | 97 | 2 | - part_d_15_20 | b | 16 | 105 | 16 | - part_d_15_20 | b | 18 | 105 | 19 | -(6 rows) - -DROP TRIGGER trans_updatetrig ON range_parted; -DROP TRIGGER trig_c1_100 ON part_c_1_100; -DROP TRIGGER trig_d1_15 ON part_d_1_15; -DROP TRIGGER trig_d15_20 ON part_d_15_20; -DROP FUNCTION func_parted_mod_b(); --- RLS policies with update-row-movement ------------------------------------------ -ALTER TABLE range_parted ENABLE ROW LEVEL SECURITY; -CREATE USER regress_range_parted_user; -GRANT ALL ON range_parted, mintab TO regress_range_parted_user; -CREATE POLICY seeall ON range_parted AS PERMISSIVE FOR SELECT USING (true); -CREATE POLICY policy_range_parted ON range_parted for UPDATE USING (true) WITH CHECK (c % 2 = 0); -:init_range_parted; -SET SESSION AUTHORIZATION regress_range_parted_user; --- This should fail with RLS violation error while moving row from --- part_a_10_a_20 to part_d_1_15, because we are setting 'c' to an odd number. -UPDATE range_parted set a = 'b', c = 151 WHERE a = 'a' and c = 200; -ERROR: new row violates row-level security policy for table "range_parted" -RESET SESSION AUTHORIZATION; --- Create a trigger on part_d_1_15 -CREATE FUNCTION func_d_1_15() RETURNS trigger AS $$ -BEGIN - NEW.c = NEW.c + 1; -- Make even numbers odd, or vice versa - return NEW; -END $$ LANGUAGE plpgsql; -CREATE TRIGGER trig_d_1_15 BEFORE INSERT ON part_d_1_15 - FOR EACH ROW EXECUTE PROCEDURE func_d_1_15(); -:init_range_parted; -SET SESSION AUTHORIZATION regress_range_parted_user; --- Here, RLS checks should succeed while moving row from part_a_10_a_20 to --- part_d_1_15. Even though the UPDATE is setting 'c' to an odd number, the --- trigger at the destination partition again makes it an even number. -UPDATE range_parted set a = 'b', c = 151 WHERE a = 'a' and c = 200; -RESET SESSION AUTHORIZATION; -:init_range_parted; -SET SESSION AUTHORIZATION regress_range_parted_user; --- This should fail with RLS violation error. Even though the UPDATE is setting --- 'c' to an even number, the trigger at the destination partition again makes --- it an odd number. -UPDATE range_parted set a = 'b', c = 150 WHERE a = 'a' and c = 200; -ERROR: new row violates row-level security policy for table "range_parted" --- Cleanup -RESET SESSION AUTHORIZATION; -DROP TRIGGER trig_d_1_15 ON part_d_1_15; -DROP FUNCTION func_d_1_15(); --- Policy expression contains SubPlan -RESET SESSION AUTHORIZATION; -:init_range_parted; -CREATE POLICY policy_range_parted_subplan on range_parted - AS RESTRICTIVE for UPDATE USING (true) - WITH CHECK ((SELECT range_parted.c <= c1 FROM mintab)); -SET SESSION AUTHORIZATION regress_range_parted_user; --- fail, mintab has row with c1 = 120 -UPDATE range_parted set a = 'b', c = 122 WHERE a = 'a' and c = 200; -ERROR: new row violates row-level security policy "policy_range_parted_subplan" for table "range_parted" --- ok -UPDATE range_parted set a = 'b', c = 120 WHERE a = 'a' and c = 200; --- RLS policy expression contains whole row. -RESET SESSION AUTHORIZATION; -:init_range_parted; -CREATE POLICY policy_range_parted_wholerow on range_parted AS RESTRICTIVE for UPDATE USING (true) - WITH CHECK (range_parted = row('b', 10, 112, 1, NULL)::range_parted); -SET SESSION AUTHORIZATION regress_range_parted_user; --- ok, should pass the RLS check -UPDATE range_parted set a = 'b', c = 112 WHERE a = 'a' and c = 200; -RESET SESSION AUTHORIZATION; -:init_range_parted; -SET SESSION AUTHORIZATION regress_range_parted_user; --- fail, the whole row RLS check should fail -UPDATE range_parted set a = 'b', c = 116 WHERE a = 'a' and c = 200; -ERROR: new row violates row-level security policy "policy_range_parted_wholerow" for table "range_parted" --- Cleanup -RESET SESSION AUTHORIZATION; -DROP POLICY policy_range_parted ON range_parted; -DROP POLICY policy_range_parted_subplan ON range_parted; -DROP POLICY policy_range_parted_wholerow ON range_parted; -REVOKE ALL ON range_parted, mintab FROM regress_range_parted_user; -DROP USER regress_range_parted_user; -DROP TABLE mintab; --- statement triggers with update row movement ---------------------------------------------------- -:init_range_parted; -CREATE FUNCTION trigfunc() returns trigger language plpgsql as -$$ - begin - raise notice 'trigger = % fired on table % during %', - TG_NAME, TG_TABLE_NAME, TG_OP; - return null; - end; -$$; --- Triggers on root partition -CREATE TRIGGER parent_delete_trig - AFTER DELETE ON range_parted for each statement execute procedure trigfunc(); -CREATE TRIGGER parent_update_trig - AFTER UPDATE ON range_parted for each statement execute procedure trigfunc(); -CREATE TRIGGER parent_insert_trig - AFTER INSERT ON range_parted for each statement execute procedure trigfunc(); --- Triggers on leaf partition part_c_1_100 -CREATE TRIGGER c1_delete_trig - AFTER DELETE ON part_c_1_100 for each statement execute procedure trigfunc(); -CREATE TRIGGER c1_update_trig - AFTER UPDATE ON part_c_1_100 for each statement execute procedure trigfunc(); -CREATE TRIGGER c1_insert_trig - AFTER INSERT ON part_c_1_100 for each statement execute procedure trigfunc(); --- Triggers on leaf partition part_d_1_15 -CREATE TRIGGER d1_delete_trig - AFTER DELETE ON part_d_1_15 for each statement execute procedure trigfunc(); -CREATE TRIGGER d1_update_trig - AFTER UPDATE ON part_d_1_15 for each statement execute procedure trigfunc(); -CREATE TRIGGER d1_insert_trig - AFTER INSERT ON part_d_1_15 for each statement execute procedure trigfunc(); --- Triggers on leaf partition part_d_15_20 -CREATE TRIGGER d15_delete_trig - AFTER DELETE ON part_d_15_20 for each statement execute procedure trigfunc(); -CREATE TRIGGER d15_update_trig - AFTER UPDATE ON part_d_15_20 for each statement execute procedure trigfunc(); -CREATE TRIGGER d15_insert_trig - AFTER INSERT ON part_d_15_20 for each statement execute procedure trigfunc(); --- Move all rows from part_c_100_200 to part_c_1_100. None of the delete or --- insert statement triggers should be fired. -UPDATE range_parted set c = c - 50 WHERE c > 97; -NOTICE: trigger = parent_update_trig fired on table range_parted during UPDATE -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 150 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 12 | 96 | 1 | - part_c_1_100 | b | 13 | 97 | 2 | - part_c_1_100 | b | 15 | 55 | 16 | - part_c_1_100 | b | 17 | 55 | 19 | -(6 rows) - -DROP TRIGGER parent_delete_trig ON range_parted; -DROP TRIGGER parent_update_trig ON range_parted; -DROP TRIGGER parent_insert_trig ON range_parted; -DROP TRIGGER c1_delete_trig ON part_c_1_100; -DROP TRIGGER c1_update_trig ON part_c_1_100; -DROP TRIGGER c1_insert_trig ON part_c_1_100; -DROP TRIGGER d1_delete_trig ON part_d_1_15; -DROP TRIGGER d1_update_trig ON part_d_1_15; -DROP TRIGGER d1_insert_trig ON part_d_1_15; -DROP TRIGGER d15_delete_trig ON part_d_15_20; -DROP TRIGGER d15_update_trig ON part_d_15_20; -DROP TRIGGER d15_insert_trig ON part_d_15_20; --- Creating default partition for range -:init_range_parted; -create table part_def partition of range_parted default; -\d+ part_def - Table "public.part_def" - Column | Type | Collation | Nullable | Default | Storage | Stats target | Description ---------+-------------------+-----------+----------+---------+----------+--------------+------------- - a | text | | | | extended | | - b | bigint | | | | plain | | - c | numeric | | | | main | | - d | integer | | | | plain | | - e | character varying | | | | extended | | -Partition of: range_parted DEFAULT -Partition constraint: (NOT ((a IS NOT NULL) AND (b IS NOT NULL) AND (((a = 'a'::text) AND (b >= '1'::bigint) AND (b < '10'::bigint)) OR ((a = 'a'::text) AND (b >= '10'::bigint) AND (b < '20'::bigint)) OR ((a = 'b'::text) AND (b >= '1'::bigint) AND (b < '10'::bigint)) OR ((a = 'b'::text) AND (b >= '10'::bigint) AND (b < '20'::bigint)) OR ((a = 'b'::text) AND (b >= '20'::bigint) AND (b < '30'::bigint))))) - -insert into range_parted values ('c', 9); --- ok -update part_def set a = 'd' where a = 'c'; --- fail -update part_def set a = 'a' where a = 'd'; -ERROR: new row for relation "part_def" violates partition constraint -DETAIL: Failing row contains (a, 9, null, null, null). -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 12 | 96 | 1 | - part_c_1_100 | b | 13 | 97 | 2 | - part_d_15_20 | b | 15 | 105 | 16 | - part_d_15_20 | b | 17 | 105 | 19 | - part_def | d | 9 | | | -(7 rows) - --- Update row movement from non-default to default partition. --- fail, default partition is not under part_a_10_a_20; -UPDATE part_a_10_a_20 set a = 'ad' WHERE a = 'a'; -ERROR: new row for relation "part_a_10_a_20" violates partition constraint -DETAIL: Failing row contains (ad, 10, 200, 1, null). --- ok -UPDATE range_parted set a = 'ad' WHERE a = 'a'; -UPDATE range_parted set a = 'bd' WHERE a = 'b'; -:show_data; - partname | a | b | c | d | e -----------+----+----+-----+----+--- - part_def | ad | 1 | 1 | 1 | - part_def | ad | 10 | 200 | 1 | - part_def | bd | 12 | 96 | 1 | - part_def | bd | 13 | 97 | 2 | - part_def | bd | 15 | 105 | 16 | - part_def | bd | 17 | 105 | 19 | - part_def | d | 9 | | | -(7 rows) - --- Update row movement from default to non-default partitions. --- ok -UPDATE range_parted set a = 'a' WHERE a = 'ad'; -UPDATE range_parted set a = 'b' WHERE a = 'bd'; -:show_data; - partname | a | b | c | d | e -----------------+---+----+-----+----+--- - part_a_10_a_20 | a | 10 | 200 | 1 | - part_a_1_a_10 | a | 1 | 1 | 1 | - part_c_1_100 | b | 12 | 96 | 1 | - part_c_1_100 | b | 13 | 97 | 2 | - part_d_15_20 | b | 15 | 105 | 16 | - part_d_15_20 | b | 17 | 105 | 19 | - part_def | d | 9 | | | -(7 rows) - --- Cleanup: range_parted no longer needed. -DROP TABLE range_parted; -CREATE TABLE list_parted ( - a text, - b int -) PARTITION BY list (a); -CREATE TABLE list_part1 PARTITION OF list_parted for VALUES in ('a', 'b'); -CREATE TABLE list_default PARTITION OF list_parted default; -INSERT into list_part1 VALUES ('a', 1); -INSERT into list_default VALUES ('d', 10); --- fail -UPDATE list_default set a = 'a' WHERE a = 'd'; -ERROR: new row for relation "list_default" violates partition constraint -DETAIL: Failing row contains (a, 10). --- ok -UPDATE list_default set a = 'x' WHERE a = 'd'; -DROP TABLE list_parted; --- Test retrieval of system columns with non-consistent partition row types. --- This is only partially supported, as seen in the results. -create table utrtest (a int, b text) partition by list (a); -create table utr1 (a int check (a in (1)), q text, b text); -create table utr2 (a int check (a in (2)), b text); -alter table utr1 drop column q; -alter table utrtest attach partition utr1 for values in (1); -alter table utrtest attach partition utr2 for values in (2); -insert into utrtest values (1, 'foo') - returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; - a | b | tableoid | xmin_ok ----+-----+----------+--------- - 1 | foo | utr1 | t -(1 row) - -insert into utrtest values (2, 'bar') - returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; -- fails -ERROR: cannot retrieve a system column in this context -insert into utrtest values (2, 'bar') - returning *, tableoid::regclass; - a | b | tableoid ----+-----+---------- - 2 | bar | utr2 -(1 row) - -update utrtest set b = b || b from (values (1), (2)) s(x) where a = s.x - returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; - a | b | x | tableoid | xmin_ok ----+--------+---+----------+--------- - 1 | foofoo | 1 | utr1 | t - 2 | barbar | 2 | utr2 | t -(2 rows) - -update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x - returning *, tableoid::regclass, xmin = pg_current_xact_id()::xid as xmin_ok; -- fails -ERROR: cannot retrieve a system column in this context -update utrtest set a = 3 - a from (values (1), (2)) s(x) where a = s.x - returning *, tableoid::regclass; - a | b | x | tableoid ----+--------+---+---------- - 2 | foofoo | 1 | utr2 - 1 | barbar | 2 | utr1 -(2 rows) - -delete from utrtest - returning *, tableoid::regclass, xmax = pg_current_xact_id()::xid as xmax_ok; - a | b | tableoid | xmax_ok ----+--------+----------+--------- - 1 | barbar | utr1 | t - 2 | foofoo | utr2 | t -(2 rows) - -drop table utrtest; --------------- --- Some more update-partition-key test scenarios below. This time use list --- partitions. --------------- --- Setup for list partitions -CREATE TABLE list_parted (a numeric, b int, c int8) PARTITION BY list (a); -CREATE TABLE sub_parted PARTITION OF list_parted for VALUES in (1) PARTITION BY list (b); -CREATE TABLE sub_part1(b int, c int8, a numeric); -ALTER TABLE sub_parted ATTACH PARTITION sub_part1 for VALUES in (1); -CREATE TABLE sub_part2(b int, c int8, a numeric); -ALTER TABLE sub_parted ATTACH PARTITION sub_part2 for VALUES in (2); -CREATE TABLE list_part1(a numeric, b int, c int8); -ALTER TABLE list_parted ATTACH PARTITION list_part1 for VALUES in (2,3); -INSERT into list_parted VALUES (2,5,50); -INSERT into list_parted VALUES (3,6,60); -INSERT into sub_parted VALUES (1,1,60); -INSERT into sub_parted VALUES (1,2,10); --- Test partition constraint violation when intermediate ancestor is used and --- constraint is inherited from upper root. -UPDATE sub_parted set a = 2 WHERE c = 10; -ERROR: new row for relation "sub_part2" violates partition constraint -DETAIL: Failing row contains (2, 10, 2). --- Test update-partition-key, where the unpruned partitions do not have their --- partition keys updated. -SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1; - tableoid | a | b | c -------------+---+---+---- - list_part1 | 2 | 5 | 50 -(1 row) - -UPDATE list_parted set b = c + a WHERE a = 2; -SELECT tableoid::regclass::text, * FROM list_parted WHERE a = 2 ORDER BY 1; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 52 | 50 -(1 row) - --- Test the case where BR UPDATE triggers change the partition key. -CREATE FUNCTION func_parted_mod_b() returns trigger as $$ -BEGIN - NEW.b = 2; -- This is changing partition key column. - return NEW; -END $$ LANGUAGE plpgsql; -CREATE TRIGGER parted_mod_b before update on sub_part1 - for each row execute procedure func_parted_mod_b(); -SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 52 | 50 - list_part1 | 3 | 6 | 60 - sub_part1 | 1 | 1 | 60 - sub_part2 | 1 | 2 | 10 -(4 rows) - --- This should do the tuple routing even though there is no explicit --- partition-key update, because there is a trigger on sub_part1. -UPDATE list_parted set c = 70 WHERE b = 1; -SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 52 | 50 - list_part1 | 3 | 6 | 60 - sub_part2 | 1 | 2 | 10 - sub_part2 | 1 | 2 | 70 -(4 rows) - -DROP TRIGGER parted_mod_b ON sub_part1; --- If BR DELETE trigger prevented DELETE from happening, we should also skip --- the INSERT if that delete is part of UPDATE=>DELETE+INSERT. -CREATE OR REPLACE FUNCTION func_parted_mod_b() returns trigger as $$ -BEGIN - raise notice 'Trigger: Got OLD row %, but returning NULL', OLD; - return NULL; -END $$ LANGUAGE plpgsql; -CREATE TRIGGER trig_skip_delete before delete on sub_part2 - for each row execute procedure func_parted_mod_b(); -UPDATE list_parted set b = 1 WHERE c = 70; -NOTICE: Trigger: Got OLD row (2,70,1), but returning NULL -SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 52 | 50 - list_part1 | 3 | 6 | 60 - sub_part2 | 1 | 2 | 10 - sub_part2 | 1 | 2 | 70 -(4 rows) - --- Drop the trigger. Now the row should be moved. -DROP TRIGGER trig_skip_delete ON sub_part2; -UPDATE list_parted set b = 1 WHERE c = 70; -SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 52 | 50 - list_part1 | 3 | 6 | 60 - sub_part1 | 1 | 1 | 70 - sub_part2 | 1 | 2 | 10 -(4 rows) - -DROP FUNCTION func_parted_mod_b(); --- UPDATE partition-key with FROM clause. If join produces multiple output --- rows for the same row to be modified, we should tuple-route the row only --- once. There should not be any rows inserted. -CREATE TABLE non_parted (id int); -INSERT into non_parted VALUES (1), (1), (1), (2), (2), (2), (3), (3), (3); -UPDATE list_parted t1 set a = 2 FROM non_parted t2 WHERE t1.a = t2.id and a = 1; -SELECT tableoid::regclass::text, * FROM list_parted ORDER BY 1, 2, 3, 4; - tableoid | a | b | c -------------+---+----+---- - list_part1 | 2 | 1 | 70 - list_part1 | 2 | 2 | 10 - list_part1 | 2 | 52 | 50 - list_part1 | 3 | 6 | 60 -(4 rows) - -DROP TABLE non_parted; --- Cleanup: list_parted no longer needed. -DROP TABLE list_parted; --- create custom operator class and hash function, for the same reason --- explained in alter_table.sql -create or replace function dummy_hashint4(a int4, seed int8) returns int8 as -$$ begin return (a + seed); end; $$ language 'plpgsql' immutable; -create operator class custom_opclass for type int4 using hash as -operator 1 = , function 2 dummy_hashint4(int4, int8); -create table hash_parted ( - a int, - b int -) partition by hash (a custom_opclass, b custom_opclass); -create table hpart1 partition of hash_parted for values with (modulus 2, remainder 1); -create table hpart2 partition of hash_parted for values with (modulus 4, remainder 2); -create table hpart3 partition of hash_parted for values with (modulus 8, remainder 0); -create table hpart4 partition of hash_parted for values with (modulus 8, remainder 4); -insert into hpart1 values (1, 1); -insert into hpart2 values (2, 5); -insert into hpart4 values (3, 4); --- fail -update hpart1 set a = 3, b=4 where a = 1; -ERROR: new row for relation "hpart1" violates partition constraint -DETAIL: Failing row contains (3, 4). --- ok, row movement -update hash_parted set b = b - 1 where b = 1; --- ok -update hash_parted set b = b + 8 where b = 1; --- cleanup -drop table hash_parted; -drop operator class custom_opclass using hash; -drop function dummy_hashint4(a int4, seed int8); +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/gin.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/gin.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/gin.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/gin.out 2022-02-13 01:12:16.158837441 +0100 @@ -185,85 +185,8 @@ lateral explain_query_json($$select * from t_gin_test_tbl where $$ || query) js, lateral execute_text_query_index($$select string_agg((i, j)::text, ' ') from t_gin_test_tbl where $$ || query) res_index, lateral execute_text_query_heap($$select string_agg((i, j)::text, ' ') from t_gin_test_tbl where $$ || query) res_heap; - query | return by index | removed by recheck | match --------------------------------------------+-----------------+--------------------+------- - i @> '{}' | 7 | 0 | t - j @> '{}' | 6 | 0 | t - i @> '{}' and j @> '{}' | 4 | 0 | t - i @> '{1}' | 5 | 0 | t - i @> '{1}' and j @> '{}' | 3 | 0 | t - i @> '{1}' and i @> '{}' and j @> '{}' | 3 | 0 | t - j @> '{10}' | 4 | 0 | t - j @> '{10}' and i @> '{}' | 3 | 0 | t - j @> '{10}' and j @> '{}' and i @> '{}' | 3 | 0 | t - i @> '{1}' and j @> '{10}' | 2 | 0 | t -(10 rows) - -reset enable_seqscan; -reset enable_bitmapscan; --- re-purpose t_gin_test_tbl to test scans involving posting trees -insert into t_gin_test_tbl select array[1, g, g/10], array[2, g, g/10] - from generate_series(1, 20000) g; -select gin_clean_pending_list('t_gin_test_tbl_i_j_idx') is not null; - ?column? ----------- - t -(1 row) - -analyze t_gin_test_tbl; -set enable_seqscan = off; -set enable_bitmapscan = on; -explain (costs off) -select count(*) from t_gin_test_tbl where j @> array[50]; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on t_gin_test_tbl - Recheck Cond: (j @> '{50}'::integer[]) - -> Bitmap Index Scan on t_gin_test_tbl_i_j_idx - Index Cond: (j @> '{50}'::integer[]) -(5 rows) - -select count(*) from t_gin_test_tbl where j @> array[50]; - count -------- - 11 -(1 row) - -explain (costs off) -select count(*) from t_gin_test_tbl where j @> array[2]; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on t_gin_test_tbl - Recheck Cond: (j @> '{2}'::integer[]) - -> Bitmap Index Scan on t_gin_test_tbl_i_j_idx - Index Cond: (j @> '{2}'::integer[]) -(5 rows) - -select count(*) from t_gin_test_tbl where j @> array[2]; - count -------- - 20000 -(1 row) - -explain (costs off) -select count(*) from t_gin_test_tbl where j @> '{}'::int[]; - QUERY PLAN ---------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on t_gin_test_tbl - Recheck Cond: (j @> '{}'::integer[]) - -> Bitmap Index Scan on t_gin_test_tbl_i_j_idx - Index Cond: (j @> '{}'::integer[]) -(5 rows) - -select count(*) from t_gin_test_tbl where j @> '{}'::int[]; - count -------- - 20006 -(1 row) - -reset enable_seqscan; -reset enable_bitmapscan; -drop table t_gin_test_tbl; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/collate.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/collate.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/collate.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/collate.out 2022-02-13 01:12:15.672169954 +0100 @@ -623,107 +623,9 @@ CREATE TABLE collate_test22 (f2 text COLLATE "POSIX"); INSERT INTO collate_test22 VALUES ('foo'), ('bar'), ('baz'); ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -- fail -ERROR: insert or update on table "collate_test22" violates foreign key constraint "collate_test22_f2_fkey" -DETAIL: Key (f2)=(baz) is not present in table "collate_test20". -DELETE FROM collate_test22 WHERE f2 = 'baz'; -ALTER TABLE collate_test22 ADD FOREIGN KEY (f2) REFERENCES collate_test20; -RESET enable_seqscan; -RESET enable_hashjoin; -RESET enable_nestloop; --- EXPLAIN -EXPLAIN (COSTS OFF) - SELECT * FROM collate_test10 ORDER BY x, y; - QUERY PLAN ----------------------------------------------- - Sort - Sort Key: x COLLATE "C", y COLLATE "POSIX" - -> Seq Scan on collate_test10 -(3 rows) - -EXPLAIN (COSTS OFF) - SELECT * FROM collate_test10 ORDER BY x DESC, y COLLATE "C" ASC NULLS FIRST; - QUERY PLAN ------------------------------------------------------------ - Sort - Sort Key: x COLLATE "C" DESC, y COLLATE "C" NULLS FIRST - -> Seq Scan on collate_test10 -(3 rows) - --- CREATE/DROP COLLATION -CREATE COLLATION mycoll1 FROM "C"; -CREATE COLLATION mycoll2 ( LC_COLLATE = "POSIX", LC_CTYPE = "POSIX" ); -CREATE COLLATION mycoll3 FROM "default"; -- intentionally unsupported -ERROR: collation "default" cannot be copied -DROP COLLATION mycoll1; -CREATE TABLE collate_test23 (f1 text collate mycoll2); -DROP COLLATION mycoll2; -- fail -ERROR: cannot drop collation mycoll2 because other objects depend on it -DETAIL: column f1 of table collate_test23 depends on collation mycoll2 -HINT: Use DROP ... CASCADE to drop the dependent objects too. --- invalid: non-lowercase quoted identifiers -CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctype" = "POSIX"); -ERROR: collation attribute "Lc_Collate" not recognized -LINE 1: CREATE COLLATION case_coll ("Lc_Collate" = "POSIX", "Lc_Ctyp... - ^ --- 9.1 bug with useless COLLATE in an expression subject to length coercion -CREATE TEMP TABLE vctable (f1 varchar(25)); -INSERT INTO vctable VALUES ('foo' COLLATE "C"); -SELECT collation for ('foo'); -- unknown type - null - pg_collation_for ------------------- - -(1 row) - -SELECT collation for ('foo'::text); - pg_collation_for ------------------- - "default" -(1 row) - -SELECT collation for ((SELECT a FROM collate_test1 LIMIT 1)); -- non-collatable type - error -ERROR: collations are not supported by type integer -SELECT collation for ((SELECT b FROM collate_test1 LIMIT 1)); - pg_collation_for ------------------- - "C" -(1 row) - --- old bug with not dropping COLLATE when coercing to non-collatable type -CREATE VIEW collate_on_int AS -SELECT c1+1 AS c1p FROM - (SELECT ('4' COLLATE "C")::INT AS c1) ss; -\d+ collate_on_int - View "collate_tests.collate_on_int" - Column | Type | Collation | Nullable | Default | Storage | Description ---------+---------+-----------+----------+---------+---------+------------- - c1p | integer | | | | plain | -View definition: - SELECT ss.c1 + 1 AS c1p - FROM ( SELECT 4 AS c1) ss; - --- --- Clean up. Many of these table names will be re-used if the user is --- trying to run any platform-specific collation tests later, so we --- must get rid of them. --- -DROP SCHEMA collate_tests CASCADE; -NOTICE: drop cascades to 19 other objects -DETAIL: drop cascades to table collate_test1 -drop cascades to table collate_test_like -drop cascades to table collate_test2 -drop cascades to type testdomain_p -drop cascades to table collate_test4 -drop cascades to table collate_test5 -drop cascades to table collate_test10 -drop cascades to view collview1 -drop cascades to view collview2 -drop cascades to view collview3 -drop cascades to type testdomain -drop cascades to function vc(text) -drop cascades to function dup(anyelement) -drop cascades to table collate_test20 -drop cascades to table collate_test21 -drop cascades to table collate_test22 -drop cascades to collation mycoll2 -drop cascades to table collate_test23 -drop cascades to view collate_on_int +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +CONTEXT: SQL statement "SELECT fk."f2" FROM ONLY "collate_tests"."collate_test22" fk LEFT OUTER JOIN ONLY "collate_tests"."collate_test20" pk ON ( pk."f1" OPERATOR(pg_catalog.=) fk."f2" COLLATE "pg_catalog"."C") WHERE pk."f1" IS NULL AND (fk."f2" IS NOT NULL)" +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/groupingsets.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/groupingsets.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/groupingsets.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/groupingsets.out 2022-02-13 01:12:15.448836243 +0100 @@ -305,1628 +305,8 @@ -- empty input with joins tests some important code paths select t1.a, t2.b, sum(t1.v), count(*) from gstest_empty t1, gstest_empty t2 group by grouping sets ((t1.a,t2.b),()); - a | b | sum | count ----+---+-----+------- - | | | 0 -(1 row) - --- simple joins, var resolution, GROUPING on join vars -select t1.a, t2.b, grouping(t1.a, t2.b), sum(t1.v), max(t2.a) - from gstest1 t1, gstest2 t2 - group by grouping sets ((t1.a, t2.b), ()); - a | b | grouping | sum | max ----+---+----------+------+----- - 1 | 1 | 0 | 420 | 1 - 1 | 2 | 0 | 120 | 2 - 2 | 1 | 0 | 105 | 1 - 2 | 2 | 0 | 30 | 2 - 3 | 1 | 0 | 231 | 1 - 3 | 2 | 0 | 66 | 2 - 4 | 1 | 0 | 259 | 1 - 4 | 2 | 0 | 74 | 2 - | | 3 | 1305 | 2 -(9 rows) - -select t1.a, t2.b, grouping(t1.a, t2.b), sum(t1.v), max(t2.a) - from gstest1 t1 join gstest2 t2 on (t1.a=t2.a) - group by grouping sets ((t1.a, t2.b), ()); - a | b | grouping | sum | max ----+---+----------+-----+----- - 1 | 1 | 0 | 420 | 1 - 1 | 2 | 0 | 60 | 1 - 2 | 2 | 0 | 15 | 2 - | | 3 | 495 | 2 -(4 rows) - -select a, b, grouping(a, b), sum(t1.v), max(t2.c) - from gstest1 t1 join gstest2 t2 using (a,b) - group by grouping sets ((a, b), ()); - a | b | grouping | sum | max ----+---+----------+-----+----- - 1 | 1 | 0 | 147 | 2 - 1 | 2 | 0 | 25 | 2 - | | 3 | 172 | 2 -(3 rows) - --- check that functionally dependent cols are not nulled -select a, d, grouping(a,b,c) - from gstest3 - group by grouping sets ((a,b), (a,c)); - a | d | grouping ----+---+---------- - 1 | 1 | 1 - 2 | 2 | 1 - 1 | 1 | 2 - 2 | 2 | 2 -(4 rows) - --- check that distinct grouping columns are kept separate --- even if they are equal() -explain (costs off) -select g as alias1, g as alias2 - from generate_series(1,3) g - group by alias1, rollup(alias2); - QUERY PLAN ------------------------------------------------- - GroupAggregate - Group Key: g, g - Group Key: g - -> Sort - Sort Key: g - -> Function Scan on generate_series g -(6 rows) - -select g as alias1, g as alias2 - from generate_series(1,3) g - group by alias1, rollup(alias2); - alias1 | alias2 ---------+-------- - 1 | 1 - 1 | - 2 | 2 - 2 | - 3 | 3 - 3 | -(6 rows) - --- check that pulled-up subquery outputs still go to null when appropriate -select four, x - from (select four, ten, 'foo'::text as x from tenk1) as t - group by grouping sets (four, x) - having x = 'foo'; - four | x -------+----- - | foo -(1 row) - -select four, x || 'x' - from (select four, ten, 'foo'::text as x from tenk1) as t - group by grouping sets (four, x) - order by four; - four | ?column? -------+---------- - 0 | - 1 | - 2 | - 3 | - | foox -(5 rows) - -select (x+y)*1, sum(z) - from (select 1 as x, 2 as y, 3 as z) s - group by grouping sets (x+y, x); - ?column? | sum -----------+----- - 3 | 3 - | 3 -(2 rows) - -select x, not x as not_x, q2 from - (select *, q1 = 1 as x from int8_tbl i1) as t - group by grouping sets(x, q2) - order by x, q2; - x | not_x | q2 ----+-------+------------------- - f | t | - | | -4567890123456789 - | | 123 - | | 456 - | | 4567890123456789 -(5 rows) - --- check qual push-down rules for a subquery with grouping sets -explain (verbose, costs off) -select * from ( - select 1 as x, q1, sum(q2) - from int8_tbl i1 - group by grouping sets(1, 2) -) ss -where x = 1 and q1 = 123; - QUERY PLAN --------------------------------------------- - Subquery Scan on ss - Output: ss.x, ss.q1, ss.sum - Filter: ((ss.x = 1) AND (ss.q1 = 123)) - -> GroupAggregate - Output: (1), i1.q1, sum(i1.q2) - Group Key: 1 - Sort Key: i1.q1 - Group Key: i1.q1 - -> Seq Scan on public.int8_tbl i1 - Output: 1, i1.q1, i1.q2 -(10 rows) - -select * from ( - select 1 as x, q1, sum(q2) - from int8_tbl i1 - group by grouping sets(1, 2) -) ss -where x = 1 and q1 = 123; - x | q1 | sum ----+----+----- -(0 rows) - --- simple rescan tests -select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by rollup (a,b); - a | b | sum ----+---+----- - 1 | 1 | 1 - 1 | 2 | 1 - 1 | 3 | 1 - 1 | | 3 - 2 | 1 | 2 - 2 | 2 | 2 - 2 | 3 | 2 - 2 | | 6 - | | 9 -(9 rows) - -select * - from (values (1),(2)) v(x), - lateral (select a, b, sum(v.x) from gstest_data(v.x) group by rollup (a,b)) s; -ERROR: aggregate functions are not allowed in FROM clause of their own query level -LINE 3: lateral (select a, b, sum(v.x) from gstest_data(v.x) ... - ^ --- min max optimization should still work with GROUP BY () -explain (costs off) - select min(unique1) from tenk1 GROUP BY (); - QUERY PLAN ------------------------------------------------------------- - Result - InitPlan 1 (returns $0) - -> Limit - -> Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 IS NOT NULL) -(5 rows) - --- Views with GROUPING SET queries -CREATE VIEW gstest_view AS select a, b, grouping(a,b), sum(c), count(*), max(c) - from gstest2 group by rollup ((a,b,c),(c,d)); -NOTICE: view "gstest_view" will be a temporary view -select pg_get_viewdef('gstest_view'::regclass, true); - pg_get_viewdef -------------------------------------------------------------------------------- - SELECT gstest2.a, + - gstest2.b, + - GROUPING(gstest2.a, gstest2.b) AS "grouping", + - sum(gstest2.c) AS sum, + - count(*) AS count, + - max(gstest2.c) AS max + - FROM gstest2 + - GROUP BY ROLLUP((gstest2.a, gstest2.b, gstest2.c), (gstest2.c, gstest2.d)); -(1 row) - --- Nested queries with 3 or more levels of nesting -select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); - grouping ----------- - 0 - 0 - 0 -(3 rows) - -select(select (select grouping(e,f) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); - grouping ----------- - 0 - 1 - 3 -(3 rows) - -select(select (select grouping(c) from (values (1)) v2(c) GROUP BY c) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP(e,f); - grouping ----------- - 0 - 0 - 0 -(3 rows) - --- Combinations of operations -select a, b, c, d from gstest2 group by rollup(a,b),grouping sets(c,d); - a | b | c | d ----+---+---+--- - 1 | 1 | 1 | - 1 | | 1 | - | | 1 | - 1 | 1 | 2 | - 1 | 2 | 2 | - 1 | | 2 | - 2 | 2 | 2 | - 2 | | 2 | - | | 2 | - 1 | 1 | | 1 - 1 | | | 1 - | | | 1 - 1 | 1 | | 2 - 1 | 2 | | 2 - 1 | | | 2 - 2 | 2 | | 2 - 2 | | | 2 - | | | 2 -(18 rows) - -select a, b from (values (1,2),(2,3)) v(a,b) group by a,b, grouping sets(a); - a | b ----+--- - 1 | 2 - 2 | 3 -(2 rows) - --- Tests for chained aggregates -select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; - a | b | grouping | sum | count | max ----+---+----------+-----+-------+----- - 1 | 1 | 0 | 21 | 2 | 11 - 1 | 2 | 0 | 25 | 2 | 13 - 1 | 3 | 0 | 14 | 1 | 14 - 2 | 3 | 0 | 15 | 1 | 15 - 3 | 3 | 0 | 16 | 1 | 16 - 3 | 4 | 0 | 17 | 1 | 17 - 4 | 1 | 0 | 37 | 2 | 19 - | | 3 | 21 | 2 | 11 - | | 3 | 21 | 2 | 11 - | | 3 | 25 | 2 | 13 - | | 3 | 25 | 2 | 13 - | | 3 | 14 | 1 | 14 - | | 3 | 14 | 1 | 14 - | | 3 | 15 | 1 | 15 - | | 3 | 15 | 1 | 15 - | | 3 | 16 | 1 | 16 - | | 3 | 16 | 1 | 16 - | | 3 | 17 | 1 | 17 - | | 3 | 17 | 1 | 17 - | | 3 | 37 | 2 | 19 - | | 3 | 37 | 2 | 19 -(21 rows) - -select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY ROLLUP((e+1),(f+1)); - grouping ----------- - 0 - 0 - 0 -(3 rows) - -select(select (select grouping(a,b) from (values (1)) v2(c)) from (values (1,2)) v1(a,b) group by (a,b)) from (values(6,7)) v3(e,f) GROUP BY CUBE((e+1),(f+1)) ORDER BY (e+1),(f+1); - grouping ----------- - 0 - 0 - 0 - 0 -(4 rows) - -select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum - from gstest2 group by cube (a,b) order by rsum, a, b; - a | b | sum | rsum ----+---+-----+------ - 1 | 1 | 8 | 8 - 1 | 2 | 2 | 10 - 1 | | 10 | 20 - 2 | 2 | 2 | 22 - 2 | | 2 | 24 - | 1 | 8 | 32 - | 2 | 4 | 36 - | | 12 | 48 -(8 rows) - -select a, b, sum(c) from (values (1,1,10),(1,1,11),(1,2,12),(1,2,13),(1,3,14),(2,3,15),(3,3,16),(3,4,17),(4,1,18),(4,1,19)) v(a,b,c) group by rollup (a,b); - a | b | sum ----+---+----- - 1 | 1 | 21 - 1 | 2 | 25 - 1 | 3 | 14 - 1 | | 60 - 2 | 3 | 15 - 2 | | 15 - 3 | 3 | 16 - 3 | 4 | 17 - 3 | | 33 - 4 | 1 | 37 - 4 | | 37 - | | 145 -(12 rows) - -select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by cube (a,b) order by a,b; - a | b | sum ----+---+----- - 1 | 1 | 1 - 1 | 2 | 1 - 1 | 3 | 1 - 1 | | 3 - 2 | 1 | 2 - 2 | 2 | 2 - 2 | 3 | 2 - 2 | | 6 - | 1 | 3 - | 2 | 3 - | 3 | 3 - | | 9 -(12 rows) - --- Test reordering of grouping sets -explain (costs off) -select * from gstest1 group by grouping sets((a,b,v),(v)) order by v,b,a; - QUERY PLAN ------------------------------------------------------------------------------- - GroupAggregate - Group Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 - Group Key: "*VALUES*".column3 - -> Sort - Sort Key: "*VALUES*".column3, "*VALUES*".column2, "*VALUES*".column1 - -> Values Scan on "*VALUES*" -(6 rows) - --- Agg level check. This query should error out. -select (select grouping(a,b) from gstest2) from gstest2 group by a,b; -ERROR: arguments to GROUPING must be grouping expressions of the associated query level -LINE 1: select (select grouping(a,b) from gstest2) from gstest2 grou... - ^ ---Nested queries -select a, b, sum(c), count(*) from gstest2 group by grouping sets (rollup(a,b),a); - a | b | sum | count ----+---+-----+------- - 1 | 1 | 8 | 7 - 1 | 2 | 2 | 1 - 1 | | 10 | 8 - 1 | | 10 | 8 - 2 | 2 | 2 | 1 - 2 | | 2 | 1 - 2 | | 2 | 1 - | | 12 | 9 -(8 rows) - --- HAVING queries -select ten, sum(distinct four) from onek a -group by grouping sets((ten,four),(ten)) -having exists (select 1 from onek b where sum(distinct a.four) = b.four); - ten | sum ------+----- - 0 | 0 - 0 | 2 - 0 | 2 - 1 | 1 - 1 | 3 - 2 | 0 - 2 | 2 - 2 | 2 - 3 | 1 - 3 | 3 - 4 | 0 - 4 | 2 - 4 | 2 - 5 | 1 - 5 | 3 - 6 | 0 - 6 | 2 - 6 | 2 - 7 | 1 - 7 | 3 - 8 | 0 - 8 | 2 - 8 | 2 - 9 | 1 - 9 | 3 -(25 rows) - --- Tests around pushdown of HAVING clauses, partially testing against previous bugs -select a,count(*) from gstest2 group by rollup(a) order by a; - a | count ----+------- - 1 | 8 - 2 | 1 - | 9 -(3 rows) - -select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; - a | count ----+------- - 2 | 1 - | 9 -(2 rows) - -explain (costs off) - select a,count(*) from gstest2 group by rollup(a) having a is distinct from 1 order by a; - QUERY PLAN ----------------------------------- - GroupAggregate - Group Key: a - Group Key: () - Filter: (a IS DISTINCT FROM 1) - -> Sort - Sort Key: a - -> Seq Scan on gstest2 -(7 rows) - -select v.c, (select count(*) from gstest2 group by () having v.c) - from (values (false),(true)) v(c) order by v.c; - c | count ----+------- - f | - t | 9 -(2 rows) - -explain (costs off) - select v.c, (select count(*) from gstest2 group by () having v.c) - from (values (false),(true)) v(c) order by v.c; - QUERY PLAN ------------------------------------------------------------ - Sort - Sort Key: "*VALUES*".column1 - -> Values Scan on "*VALUES*" - SubPlan 1 - -> Aggregate - Group Key: () - Filter: "*VALUES*".column1 - -> Result - One-Time Filter: "*VALUES*".column1 - -> Seq Scan on gstest2 -(10 rows) - --- HAVING with GROUPING queries -select ten, grouping(ten) from onek -group by grouping sets(ten) having grouping(ten) >= 0 -order by 2,1; - ten | grouping ------+---------- - 0 | 0 - 1 | 0 - 2 | 0 - 3 | 0 - 4 | 0 - 5 | 0 - 6 | 0 - 7 | 0 - 8 | 0 - 9 | 0 -(10 rows) - -select ten, grouping(ten) from onek -group by grouping sets(ten, four) having grouping(ten) > 0 -order by 2,1; - ten | grouping ------+---------- - | 1 - | 1 - | 1 - | 1 -(4 rows) - -select ten, grouping(ten) from onek -group by rollup(ten) having grouping(ten) > 0 -order by 2,1; - ten | grouping ------+---------- - | 1 -(1 row) - -select ten, grouping(ten) from onek -group by cube(ten) having grouping(ten) > 0 -order by 2,1; - ten | grouping ------+---------- - | 1 -(1 row) - -select ten, grouping(ten) from onek -group by (ten) having grouping(ten) >= 0 -order by 2,1; - ten | grouping ------+---------- - 0 | 0 - 1 | 0 - 2 | 0 - 3 | 0 - 4 | 0 - 5 | 0 - 6 | 0 - 7 | 0 - 8 | 0 - 9 | 0 -(10 rows) - --- FILTER queries -select ten, sum(distinct four) filter (where four::text ~ '123') from onek a -group by rollup(ten); - ten | sum ------+----- - 0 | - 1 | - 2 | - 3 | - 4 | - 5 | - 6 | - 7 | - 8 | - 9 | - | -(11 rows) - --- More rescan tests -select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; - a | a | four | ten | count ----+---+------+-----+------- - 1 | 1 | 0 | 0 | 50 - 1 | 1 | 0 | 2 | 50 - 1 | 1 | 0 | 4 | 50 - 1 | 1 | 0 | 6 | 50 - 1 | 1 | 0 | 8 | 50 - 1 | 1 | 0 | | 250 - 1 | 1 | 1 | 1 | 50 - 1 | 1 | 1 | 3 | 50 - 1 | 1 | 1 | 5 | 50 - 1 | 1 | 1 | 7 | 50 - 1 | 1 | 1 | 9 | 50 - 1 | 1 | 1 | | 250 - 1 | 1 | 2 | 0 | 50 - 1 | 1 | 2 | 2 | 50 - 1 | 1 | 2 | 4 | 50 - 1 | 1 | 2 | 6 | 50 - 1 | 1 | 2 | 8 | 50 - 1 | 1 | 2 | | 250 - 1 | 1 | 3 | 1 | 50 - 1 | 1 | 3 | 3 | 50 - 1 | 1 | 3 | 5 | 50 - 1 | 1 | 3 | 7 | 50 - 1 | 1 | 3 | 9 | 50 - 1 | 1 | 3 | | 250 - 1 | 1 | | 0 | 100 - 1 | 1 | | 1 | 100 - 1 | 1 | | 2 | 100 - 1 | 1 | | 3 | 100 - 1 | 1 | | 4 | 100 - 1 | 1 | | 5 | 100 - 1 | 1 | | 6 | 100 - 1 | 1 | | 7 | 100 - 1 | 1 | | 8 | 100 - 1 | 1 | | 9 | 100 - 1 | 1 | | | 1000 - 2 | 2 | 0 | 0 | 50 - 2 | 2 | 0 | 2 | 50 - 2 | 2 | 0 | 4 | 50 - 2 | 2 | 0 | 6 | 50 - 2 | 2 | 0 | 8 | 50 - 2 | 2 | 0 | | 250 - 2 | 2 | 1 | 1 | 50 - 2 | 2 | 1 | 3 | 50 - 2 | 2 | 1 | 5 | 50 - 2 | 2 | 1 | 7 | 50 - 2 | 2 | 1 | 9 | 50 - 2 | 2 | 1 | | 250 - 2 | 2 | 2 | 0 | 50 - 2 | 2 | 2 | 2 | 50 - 2 | 2 | 2 | 4 | 50 - 2 | 2 | 2 | 6 | 50 - 2 | 2 | 2 | 8 | 50 - 2 | 2 | 2 | | 250 - 2 | 2 | 3 | 1 | 50 - 2 | 2 | 3 | 3 | 50 - 2 | 2 | 3 | 5 | 50 - 2 | 2 | 3 | 7 | 50 - 2 | 2 | 3 | 9 | 50 - 2 | 2 | 3 | | 250 - 2 | 2 | | 0 | 100 - 2 | 2 | | 1 | 100 - 2 | 2 | | 2 | 100 - 2 | 2 | | 3 | 100 - 2 | 2 | | 4 | 100 - 2 | 2 | | 5 | 100 - 2 | 2 | | 6 | 100 - 2 | 2 | | 7 | 100 - 2 | 2 | | 8 | 100 - 2 | 2 | | 9 | 100 - 2 | 2 | | | 1000 -(70 rows) - -select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); - array ------------------------------------------------------------------------------------------------------------------------------------------------------- - {"(1,0,0,250)","(1,0,2,250)","(1,0,,500)","(1,1,1,250)","(1,1,3,250)","(1,1,,500)","(1,,0,250)","(1,,1,250)","(1,,2,250)","(1,,3,250)","(1,,,1000)"} - {"(2,0,0,250)","(2,0,2,250)","(2,0,,500)","(2,1,1,250)","(2,1,3,250)","(2,1,,500)","(2,,0,250)","(2,,1,250)","(2,,2,250)","(2,,3,250)","(2,,,1000)"} -(2 rows) - --- Grouping on text columns -select sum(ten) from onek group by two, rollup(four::text) order by 1; - sum ------- - 1000 - 1000 - 1250 - 1250 - 2000 - 2500 -(6 rows) - -select sum(ten) from onek group by rollup(four::text), two order by 1; - sum ------- - 1000 - 1000 - 1250 - 1250 - 2000 - 2500 -(6 rows) - --- hashing support -set enable_hashagg = true; --- failure cases -select count(*) from gstest4 group by rollup(unhashable_col,unsortable_col); -ERROR: could not implement GROUP BY -DETAIL: Some of the datatypes only support hashing, while others only support sorting. -select array_agg(v order by v) from gstest4 group by grouping sets ((id,unsortable_col),(id)); -ERROR: could not implement GROUP BY -DETAIL: Some of the datatypes only support hashing, while others only support sorting. --- simple cases -select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by grouping sets ((a),(b)) order by 3,1,2; - a | b | grouping | sum | count | max ----+---+----------+-----+-------+----- - 1 | | 1 | 60 | 5 | 14 - 2 | | 1 | 15 | 1 | 15 - 3 | | 1 | 33 | 2 | 17 - 4 | | 1 | 37 | 2 | 19 - | 1 | 2 | 58 | 4 | 19 - | 2 | 2 | 25 | 2 | 13 - | 3 | 2 | 45 | 3 | 16 - | 4 | 2 | 17 | 1 | 17 -(8 rows) - -explain (costs off) select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by grouping sets ((a),(b)) order by 3,1,2; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), "*VALUES*".column1, "*VALUES*".column2 - -> HashAggregate - Hash Key: "*VALUES*".column1 - Hash Key: "*VALUES*".column2 - -> Values Scan on "*VALUES*" -(6 rows) - -select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by cube(a,b) order by 3,1,2; - a | b | grouping | sum | count | max ----+---+----------+-----+-------+----- - 1 | 1 | 0 | 21 | 2 | 11 - 1 | 2 | 0 | 25 | 2 | 13 - 1 | 3 | 0 | 14 | 1 | 14 - 2 | 3 | 0 | 15 | 1 | 15 - 3 | 3 | 0 | 16 | 1 | 16 - 3 | 4 | 0 | 17 | 1 | 17 - 4 | 1 | 0 | 37 | 2 | 19 - 1 | | 1 | 60 | 5 | 14 - 2 | | 1 | 15 | 1 | 15 - 3 | | 1 | 33 | 2 | 17 - 4 | | 1 | 37 | 2 | 19 - | 1 | 2 | 58 | 4 | 19 - | 2 | 2 | 25 | 2 | 13 - | 3 | 2 | 45 | 3 | 16 - | 4 | 2 | 17 | 1 | 17 - | | 3 | 145 | 10 | 19 -(16 rows) - -explain (costs off) select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by cube(a,b) order by 3,1,2; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), "*VALUES*".column1, "*VALUES*".column2 - -> MixedAggregate - Hash Key: "*VALUES*".column1, "*VALUES*".column2 - Hash Key: "*VALUES*".column1 - Hash Key: "*VALUES*".column2 - Group Key: () - -> Values Scan on "*VALUES*" -(8 rows) - --- shouldn't try and hash -explain (costs off) - select a, b, grouping(a,b), array_agg(v order by v) - from gstest1 group by cube(a,b); - QUERY PLAN ----------------------------------------------------------- - GroupAggregate - Group Key: "*VALUES*".column1, "*VALUES*".column2 - Group Key: "*VALUES*".column1 - Group Key: () - Sort Key: "*VALUES*".column2 - Group Key: "*VALUES*".column2 - -> Sort - Sort Key: "*VALUES*".column1, "*VALUES*".column2 - -> Values Scan on "*VALUES*" -(9 rows) - --- unsortable cases -select unsortable_col, count(*) - from gstest4 group by grouping sets ((unsortable_col),(unsortable_col)) - order by unsortable_col::text; - unsortable_col | count -----------------+------- - 1 | 4 - 1 | 4 - 2 | 4 - 2 | 4 -(4 rows) - --- mixed hashable/sortable cases -select unhashable_col, unsortable_col, - grouping(unhashable_col, unsortable_col), - count(*), sum(v) - from gstest4 group by grouping sets ((unhashable_col),(unsortable_col)) - order by 3, 5; - unhashable_col | unsortable_col | grouping | count | sum -----------------+----------------+----------+-------+----- - 0000 | | 1 | 2 | 17 - 0001 | | 1 | 2 | 34 - 0010 | | 1 | 2 | 68 - 0011 | | 1 | 2 | 136 - | 2 | 2 | 4 | 60 - | 1 | 2 | 4 | 195 -(6 rows) - -explain (costs off) - select unhashable_col, unsortable_col, - grouping(unhashable_col, unsortable_col), - count(*), sum(v) - from gstest4 group by grouping sets ((unhashable_col),(unsortable_col)) - order by 3,5; - QUERY PLAN ------------------------------------------------------------------- - Sort - Sort Key: (GROUPING(unhashable_col, unsortable_col)), (sum(v)) - -> MixedAggregate - Hash Key: unsortable_col - Group Key: unhashable_col - -> Sort - Sort Key: unhashable_col - -> Seq Scan on gstest4 -(8 rows) - -select unhashable_col, unsortable_col, - grouping(unhashable_col, unsortable_col), - count(*), sum(v) - from gstest4 group by grouping sets ((v,unhashable_col),(v,unsortable_col)) - order by 3,5; - unhashable_col | unsortable_col | grouping | count | sum -----------------+----------------+----------+-------+----- - 0000 | | 1 | 1 | 1 - 0001 | | 1 | 1 | 2 - 0010 | | 1 | 1 | 4 - 0011 | | 1 | 1 | 8 - 0000 | | 1 | 1 | 16 - 0001 | | 1 | 1 | 32 - 0010 | | 1 | 1 | 64 - 0011 | | 1 | 1 | 128 - | 1 | 2 | 1 | 1 - | 1 | 2 | 1 | 2 - | 2 | 2 | 1 | 4 - | 2 | 2 | 1 | 8 - | 2 | 2 | 1 | 16 - | 2 | 2 | 1 | 32 - | 1 | 2 | 1 | 64 - | 1 | 2 | 1 | 128 -(16 rows) - -explain (costs off) - select unhashable_col, unsortable_col, - grouping(unhashable_col, unsortable_col), - count(*), sum(v) - from gstest4 group by grouping sets ((v,unhashable_col),(v,unsortable_col)) - order by 3,5; - QUERY PLAN ------------------------------------------------------------------- - Sort - Sort Key: (GROUPING(unhashable_col, unsortable_col)), (sum(v)) - -> MixedAggregate - Hash Key: v, unsortable_col - Group Key: v, unhashable_col - -> Sort - Sort Key: v, unhashable_col - -> Seq Scan on gstest4 -(8 rows) - --- empty input: first is 0 rows, second 1, third 3 etc. -select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); - a | b | sum | count ----+---+-----+------- -(0 rows) - -explain (costs off) - select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),a); - QUERY PLAN --------------------------------- - HashAggregate - Hash Key: a, b - Hash Key: a - -> Seq Scan on gstest_empty -(4 rows) - -select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),()); - a | b | sum | count ----+---+-----+------- - | | | 0 -(1 row) - -select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()); - a | b | sum | count ----+---+-----+------- - | | | 0 - | | | 0 - | | | 0 -(3 rows) - -explain (costs off) - select a, b, sum(v), count(*) from gstest_empty group by grouping sets ((a,b),(),(),()); - QUERY PLAN --------------------------------- - MixedAggregate - Hash Key: a, b - Group Key: () - Group Key: () - Group Key: () - -> Seq Scan on gstest_empty -(6 rows) - -select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()); - sum | count ------+------- - | 0 - | 0 - | 0 -(3 rows) - -explain (costs off) - select sum(v), count(*) from gstest_empty group by grouping sets ((),(),()); - QUERY PLAN --------------------------------- - Aggregate - Group Key: () - Group Key: () - Group Key: () - -> Seq Scan on gstest_empty -(5 rows) - --- check that functionally dependent cols are not nulled -select a, d, grouping(a,b,c) - from gstest3 - group by grouping sets ((a,b), (a,c)); - a | d | grouping ----+---+---------- - 1 | 1 | 1 - 2 | 2 | 1 - 1 | 1 | 2 - 2 | 2 | 2 -(4 rows) - -explain (costs off) - select a, d, grouping(a,b,c) - from gstest3 - group by grouping sets ((a,b), (a,c)); - QUERY PLAN ---------------------------- - HashAggregate - Hash Key: a, b - Hash Key: a, c - -> Seq Scan on gstest3 -(4 rows) - --- simple rescan tests -select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by grouping sets (a,b) - order by 1, 2, 3; - a | b | sum ----+---+----- - 1 | | 3 - 2 | | 6 - | 1 | 3 - | 2 | 3 - | 3 | 3 -(5 rows) - -explain (costs off) - select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by grouping sets (a,b) - order by 3, 1, 2; - QUERY PLAN ---------------------------------------------------------------------- - Sort - Sort Key: (sum("*VALUES*".column1)), gstest_data.a, gstest_data.b - -> HashAggregate - Hash Key: gstest_data.a - Hash Key: gstest_data.b - -> Nested Loop - -> Values Scan on "*VALUES*" - -> Function Scan on gstest_data -(8 rows) - -select * - from (values (1),(2)) v(x), - lateral (select a, b, sum(v.x) from gstest_data(v.x) group by grouping sets (a,b)) s; -ERROR: aggregate functions are not allowed in FROM clause of their own query level -LINE 3: lateral (select a, b, sum(v.x) from gstest_data(v.x) ... - ^ -explain (costs off) - select * - from (values (1),(2)) v(x), - lateral (select a, b, sum(v.x) from gstest_data(v.x) group by grouping sets (a,b)) s; -ERROR: aggregate functions are not allowed in FROM clause of their own query level -LINE 4: lateral (select a, b, sum(v.x) from gstest_data(v.x... - ^ --- Tests for chained aggregates -select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; - a | b | grouping | sum | count | max ----+---+----------+-----+-------+----- - 1 | 1 | 0 | 21 | 2 | 11 - 1 | 2 | 0 | 25 | 2 | 13 - 1 | 3 | 0 | 14 | 1 | 14 - 2 | 3 | 0 | 15 | 1 | 15 - 3 | 3 | 0 | 16 | 1 | 16 - 3 | 4 | 0 | 17 | 1 | 17 - 4 | 1 | 0 | 37 | 2 | 19 - | | 3 | 21 | 2 | 11 - | | 3 | 21 | 2 | 11 - | | 3 | 25 | 2 | 13 - | | 3 | 25 | 2 | 13 - | | 3 | 14 | 1 | 14 - | | 3 | 14 | 1 | 14 - | | 3 | 15 | 1 | 15 - | | 3 | 15 | 1 | 15 - | | 3 | 16 | 1 | 16 - | | 3 | 16 | 1 | 16 - | | 3 | 17 | 1 | 17 - | | 3 | 17 | 1 | 17 - | | 3 | 37 | 2 | 19 - | | 3 | 37 | 2 | 19 -(21 rows) - -explain (costs off) - select a, b, grouping(a,b), sum(v), count(*), max(v) - from gstest1 group by grouping sets ((a,b),(a+1,b+1),(a+2,b+2)) order by 3,6; - QUERY PLAN -------------------------------------------------------------------------------------------- - Sort - Sort Key: (GROUPING("*VALUES*".column1, "*VALUES*".column2)), (max("*VALUES*".column3)) - -> HashAggregate - Hash Key: "*VALUES*".column1, "*VALUES*".column2 - Hash Key: ("*VALUES*".column1 + 1), ("*VALUES*".column2 + 1) - Hash Key: ("*VALUES*".column1 + 2), ("*VALUES*".column2 + 2) - -> Values Scan on "*VALUES*" -(7 rows) - -select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum - from gstest2 group by cube (a,b) order by rsum, a, b; - a | b | sum | rsum ----+---+-----+------ - 1 | 1 | 8 | 8 - 1 | 2 | 2 | 10 - 1 | | 10 | 20 - 2 | 2 | 2 | 22 - 2 | | 2 | 24 - | 1 | 8 | 32 - | 2 | 4 | 36 - | | 12 | 48 -(8 rows) - -explain (costs off) - select a, b, sum(c), sum(sum(c)) over (order by a,b) as rsum - from gstest2 group by cube (a,b) order by rsum, a, b; - QUERY PLAN ---------------------------------------------- - Sort - Sort Key: (sum((sum(c))) OVER (?)), a, b - -> WindowAgg - -> Sort - Sort Key: a, b - -> MixedAggregate - Hash Key: a, b - Hash Key: a - Hash Key: b - Group Key: () - -> Seq Scan on gstest2 -(11 rows) - -select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by cube (a,b) order by a,b; - a | b | sum ----+---+----- - 1 | 1 | 1 - 1 | 2 | 1 - 1 | 3 | 1 - 1 | | 3 - 2 | 1 | 2 - 2 | 2 | 2 - 2 | 3 | 2 - 2 | | 6 - | 1 | 3 - | 2 | 3 - | 3 | 3 - | | 9 -(12 rows) - -explain (costs off) - select a, b, sum(v.x) - from (values (1),(2)) v(x), gstest_data(v.x) - group by cube (a,b) order by a,b; - QUERY PLAN ------------------------------------------------- - Sort - Sort Key: gstest_data.a, gstest_data.b - -> MixedAggregate - Hash Key: gstest_data.a, gstest_data.b - Hash Key: gstest_data.a - Hash Key: gstest_data.b - Group Key: () - -> Nested Loop - -> Values Scan on "*VALUES*" - -> Function Scan on gstest_data -(10 rows) - --- Verify that we correctly handle the child node returning a --- non-minimal slot, which happens if the input is pre-sorted, --- e.g. due to an index scan. -BEGIN; -SET LOCAL enable_hashagg = false; -EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; - QUERY PLAN ---------------------------------------- - Sort - Sort Key: a, b - -> GroupAggregate - Group Key: a - Group Key: () - Sort Key: b - Group Key: b - -> Sort - Sort Key: a - -> Seq Scan on gstest3 -(10 rows) - -SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; - a | b | count | max | max ----+---+-------+-----+----- - 1 | | 1 | 1 | 1 - 2 | | 1 | 2 | 2 - | 1 | 1 | 1 | 1 - | 2 | 1 | 2 | 2 - | | 2 | 2 | 2 -(5 rows) - -SET LOCAL enable_seqscan = false; -EXPLAIN (COSTS OFF) SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; - QUERY PLAN ------------------------------------------------------- - Sort - Sort Key: a, b - -> GroupAggregate - Group Key: a - Group Key: () - Sort Key: b - Group Key: b - -> Index Scan using gstest3_pkey on gstest3 -(8 rows) - -SELECT a, b, count(*), max(a), max(b) FROM gstest3 GROUP BY GROUPING SETS(a, b,()) ORDER BY a, b; - a | b | count | max | max ----+---+-------+-----+----- - 1 | | 1 | 1 | 1 - 2 | | 1 | 2 | 2 - | 1 | 1 | 1 | 1 - | 2 | 1 | 2 | 2 - | | 2 | 2 | 2 -(5 rows) - -COMMIT; --- More rescan tests -select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by cube(four,ten)) s on true order by v.a,four,ten; - a | a | four | ten | count ----+---+------+-----+------- - 1 | 1 | 0 | 0 | 50 - 1 | 1 | 0 | 2 | 50 - 1 | 1 | 0 | 4 | 50 - 1 | 1 | 0 | 6 | 50 - 1 | 1 | 0 | 8 | 50 - 1 | 1 | 0 | | 250 - 1 | 1 | 1 | 1 | 50 - 1 | 1 | 1 | 3 | 50 - 1 | 1 | 1 | 5 | 50 - 1 | 1 | 1 | 7 | 50 - 1 | 1 | 1 | 9 | 50 - 1 | 1 | 1 | | 250 - 1 | 1 | 2 | 0 | 50 - 1 | 1 | 2 | 2 | 50 - 1 | 1 | 2 | 4 | 50 - 1 | 1 | 2 | 6 | 50 - 1 | 1 | 2 | 8 | 50 - 1 | 1 | 2 | | 250 - 1 | 1 | 3 | 1 | 50 - 1 | 1 | 3 | 3 | 50 - 1 | 1 | 3 | 5 | 50 - 1 | 1 | 3 | 7 | 50 - 1 | 1 | 3 | 9 | 50 - 1 | 1 | 3 | | 250 - 1 | 1 | | 0 | 100 - 1 | 1 | | 1 | 100 - 1 | 1 | | 2 | 100 - 1 | 1 | | 3 | 100 - 1 | 1 | | 4 | 100 - 1 | 1 | | 5 | 100 - 1 | 1 | | 6 | 100 - 1 | 1 | | 7 | 100 - 1 | 1 | | 8 | 100 - 1 | 1 | | 9 | 100 - 1 | 1 | | | 1000 - 2 | 2 | 0 | 0 | 50 - 2 | 2 | 0 | 2 | 50 - 2 | 2 | 0 | 4 | 50 - 2 | 2 | 0 | 6 | 50 - 2 | 2 | 0 | 8 | 50 - 2 | 2 | 0 | | 250 - 2 | 2 | 1 | 1 | 50 - 2 | 2 | 1 | 3 | 50 - 2 | 2 | 1 | 5 | 50 - 2 | 2 | 1 | 7 | 50 - 2 | 2 | 1 | 9 | 50 - 2 | 2 | 1 | | 250 - 2 | 2 | 2 | 0 | 50 - 2 | 2 | 2 | 2 | 50 - 2 | 2 | 2 | 4 | 50 - 2 | 2 | 2 | 6 | 50 - 2 | 2 | 2 | 8 | 50 - 2 | 2 | 2 | | 250 - 2 | 2 | 3 | 1 | 50 - 2 | 2 | 3 | 3 | 50 - 2 | 2 | 3 | 5 | 50 - 2 | 2 | 3 | 7 | 50 - 2 | 2 | 3 | 9 | 50 - 2 | 2 | 3 | | 250 - 2 | 2 | | 0 | 100 - 2 | 2 | | 1 | 100 - 2 | 2 | | 2 | 100 - 2 | 2 | | 3 | 100 - 2 | 2 | | 4 | 100 - 2 | 2 | | 5 | 100 - 2 | 2 | | 6 | 100 - 2 | 2 | | 7 | 100 - 2 | 2 | | 8 | 100 - 2 | 2 | | 9 | 100 - 2 | 2 | | | 1000 -(70 rows) - -select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by cube(two,four) order by two,four) s1) from (values (1),(2)) v(a); - array ------------------------------------------------------------------------------------------------------------------------------------------------------- - {"(1,0,0,250)","(1,0,2,250)","(1,0,,500)","(1,1,1,250)","(1,1,3,250)","(1,1,,500)","(1,,0,250)","(1,,1,250)","(1,,2,250)","(1,,3,250)","(1,,,1000)"} - {"(2,0,0,250)","(2,0,2,250)","(2,0,,500)","(2,1,1,250)","(2,1,3,250)","(2,1,,500)","(2,,0,250)","(2,,1,250)","(2,,2,250)","(2,,3,250)","(2,,,1000)"} -(2 rows) - --- Rescan logic changes when there are no empty grouping sets, so test --- that too: -select * from (values (1),(2)) v(a) left join lateral (select v.a, four, ten, count(*) from onek group by grouping sets(four,ten)) s on true order by v.a,four,ten; - a | a | four | ten | count ----+---+------+-----+------- - 1 | 1 | 0 | | 250 - 1 | 1 | 1 | | 250 - 1 | 1 | 2 | | 250 - 1 | 1 | 3 | | 250 - 1 | 1 | | 0 | 100 - 1 | 1 | | 1 | 100 - 1 | 1 | | 2 | 100 - 1 | 1 | | 3 | 100 - 1 | 1 | | 4 | 100 - 1 | 1 | | 5 | 100 - 1 | 1 | | 6 | 100 - 1 | 1 | | 7 | 100 - 1 | 1 | | 8 | 100 - 1 | 1 | | 9 | 100 - 2 | 2 | 0 | | 250 - 2 | 2 | 1 | | 250 - 2 | 2 | 2 | | 250 - 2 | 2 | 3 | | 250 - 2 | 2 | | 0 | 100 - 2 | 2 | | 1 | 100 - 2 | 2 | | 2 | 100 - 2 | 2 | | 3 | 100 - 2 | 2 | | 4 | 100 - 2 | 2 | | 5 | 100 - 2 | 2 | | 6 | 100 - 2 | 2 | | 7 | 100 - 2 | 2 | | 8 | 100 - 2 | 2 | | 9 | 100 -(28 rows) - -select array(select row(v.a,s1.*) from (select two,four, count(*) from onek group by grouping sets(two,four) order by two,four) s1) from (values (1),(2)) v(a); - array ---------------------------------------------------------------------------------- - {"(1,0,,500)","(1,1,,500)","(1,,0,250)","(1,,1,250)","(1,,2,250)","(1,,3,250)"} - {"(2,0,,500)","(2,1,,500)","(2,,0,250)","(2,,1,250)","(2,,2,250)","(2,,3,250)"} -(2 rows) - --- test the knapsack -set enable_indexscan = false; -set work_mem = '64kB'; -explain (costs off) - select unique1, - count(two), count(four), count(ten), - count(hundred), count(thousand), count(twothousand), - count(*) - from tenk1 group by grouping sets (unique1,twothousand,thousand,hundred,ten,four,two); - QUERY PLAN -------------------------------- - MixedAggregate - Hash Key: two - Hash Key: four - Hash Key: ten - Hash Key: hundred - Group Key: unique1 - Sort Key: twothousand - Group Key: twothousand - Sort Key: thousand - Group Key: thousand - -> Sort - Sort Key: unique1 - -> Seq Scan on tenk1 -(13 rows) - -explain (costs off) - select unique1, - count(two), count(four), count(ten), - count(hundred), count(thousand), count(twothousand), - count(*) - from tenk1 group by grouping sets (unique1,hundred,ten,four,two); - QUERY PLAN -------------------------------- - MixedAggregate - Hash Key: two - Hash Key: four - Hash Key: ten - Hash Key: hundred - Group Key: unique1 - -> Sort - Sort Key: unique1 - -> Seq Scan on tenk1 -(9 rows) - -set work_mem = '384kB'; -explain (costs off) - select unique1, - count(two), count(four), count(ten), - count(hundred), count(thousand), count(twothousand), - count(*) - from tenk1 group by grouping sets (unique1,twothousand,thousand,hundred,ten,four,two); - QUERY PLAN -------------------------------- - MixedAggregate - Hash Key: two - Hash Key: four - Hash Key: ten - Hash Key: hundred - Hash Key: thousand - Group Key: unique1 - Sort Key: twothousand - Group Key: twothousand - -> Sort - Sort Key: unique1 - -> Seq Scan on tenk1 -(12 rows) - --- check collation-sensitive matching between grouping expressions --- (similar to a check for aggregates, but there are additional code --- paths for GROUPING, so check again here) -select v||'a', case grouping(v||'a') when 1 then 1 else 0 end, count(*) - from unnest(array[1,1], array['a','b']) u(i,v) - group by rollup(i, v||'a') order by 1,3; - ?column? | case | count -----------+------+------- - aa | 0 | 1 - ba | 0 | 1 - | 1 | 2 - | 1 | 2 -(4 rows) - -select v||'a', case when grouping(v||'a') = 1 then 1 else 0 end, count(*) - from unnest(array[1,1], array['a','b']) u(i,v) - group by rollup(i, v||'a') order by 1,3; - ?column? | case | count -----------+------+------- - aa | 0 | 1 - ba | 0 | 1 - | 1 | 2 - | 1 | 2 -(4 rows) - --- Bug #16784 -create table bug_16784(i int, j int); -analyze bug_16784; -alter table bug_16784 set (autovacuum_enabled = 'false'); -update pg_class set reltuples = 10 where relname='bug_16784'; -insert into bug_16784 select g/10, g from generate_series(1,40) g; -set work_mem='64kB'; -set enable_sort = false; -select * from - (values (1),(2)) v(a), - lateral (select a, i, j, count(*) from - bug_16784 group by cube(i,j)) s - order by v.a, i, j; - a | a | i | j | count ----+---+---+----+------- - 1 | 1 | 0 | 1 | 1 - 1 | 1 | 0 | 2 | 1 - 1 | 1 | 0 | 3 | 1 - 1 | 1 | 0 | 4 | 1 - 1 | 1 | 0 | 5 | 1 - 1 | 1 | 0 | 6 | 1 - 1 | 1 | 0 | 7 | 1 - 1 | 1 | 0 | 8 | 1 - 1 | 1 | 0 | 9 | 1 - 1 | 1 | 0 | | 9 - 1 | 1 | 1 | 10 | 1 - 1 | 1 | 1 | 11 | 1 - 1 | 1 | 1 | 12 | 1 - 1 | 1 | 1 | 13 | 1 - 1 | 1 | 1 | 14 | 1 - 1 | 1 | 1 | 15 | 1 - 1 | 1 | 1 | 16 | 1 - 1 | 1 | 1 | 17 | 1 - 1 | 1 | 1 | 18 | 1 - 1 | 1 | 1 | 19 | 1 - 1 | 1 | 1 | | 10 - 1 | 1 | 2 | 20 | 1 - 1 | 1 | 2 | 21 | 1 - 1 | 1 | 2 | 22 | 1 - 1 | 1 | 2 | 23 | 1 - 1 | 1 | 2 | 24 | 1 - 1 | 1 | 2 | 25 | 1 - 1 | 1 | 2 | 26 | 1 - 1 | 1 | 2 | 27 | 1 - 1 | 1 | 2 | 28 | 1 - 1 | 1 | 2 | 29 | 1 - 1 | 1 | 2 | | 10 - 1 | 1 | 3 | 30 | 1 - 1 | 1 | 3 | 31 | 1 - 1 | 1 | 3 | 32 | 1 - 1 | 1 | 3 | 33 | 1 - 1 | 1 | 3 | 34 | 1 - 1 | 1 | 3 | 35 | 1 - 1 | 1 | 3 | 36 | 1 - 1 | 1 | 3 | 37 | 1 - 1 | 1 | 3 | 38 | 1 - 1 | 1 | 3 | 39 | 1 - 1 | 1 | 3 | | 10 - 1 | 1 | 4 | 40 | 1 - 1 | 1 | 4 | | 1 - 1 | 1 | | 1 | 1 - 1 | 1 | | 2 | 1 - 1 | 1 | | 3 | 1 - 1 | 1 | | 4 | 1 - 1 | 1 | | 5 | 1 - 1 | 1 | | 6 | 1 - 1 | 1 | | 7 | 1 - 1 | 1 | | 8 | 1 - 1 | 1 | | 9 | 1 - 1 | 1 | | 10 | 1 - 1 | 1 | | 11 | 1 - 1 | 1 | | 12 | 1 - 1 | 1 | | 13 | 1 - 1 | 1 | | 14 | 1 - 1 | 1 | | 15 | 1 - 1 | 1 | | 16 | 1 - 1 | 1 | | 17 | 1 - 1 | 1 | | 18 | 1 - 1 | 1 | | 19 | 1 - 1 | 1 | | 20 | 1 - 1 | 1 | | 21 | 1 - 1 | 1 | | 22 | 1 - 1 | 1 | | 23 | 1 - 1 | 1 | | 24 | 1 - 1 | 1 | | 25 | 1 - 1 | 1 | | 26 | 1 - 1 | 1 | | 27 | 1 - 1 | 1 | | 28 | 1 - 1 | 1 | | 29 | 1 - 1 | 1 | | 30 | 1 - 1 | 1 | | 31 | 1 - 1 | 1 | | 32 | 1 - 1 | 1 | | 33 | 1 - 1 | 1 | | 34 | 1 - 1 | 1 | | 35 | 1 - 1 | 1 | | 36 | 1 - 1 | 1 | | 37 | 1 - 1 | 1 | | 38 | 1 - 1 | 1 | | 39 | 1 - 1 | 1 | | 40 | 1 - 1 | 1 | | | 40 - 2 | 2 | 0 | 1 | 1 - 2 | 2 | 0 | 2 | 1 - 2 | 2 | 0 | 3 | 1 - 2 | 2 | 0 | 4 | 1 - 2 | 2 | 0 | 5 | 1 - 2 | 2 | 0 | 6 | 1 - 2 | 2 | 0 | 7 | 1 - 2 | 2 | 0 | 8 | 1 - 2 | 2 | 0 | 9 | 1 - 2 | 2 | 0 | | 9 - 2 | 2 | 1 | 10 | 1 - 2 | 2 | 1 | 11 | 1 - 2 | 2 | 1 | 12 | 1 - 2 | 2 | 1 | 13 | 1 - 2 | 2 | 1 | 14 | 1 - 2 | 2 | 1 | 15 | 1 - 2 | 2 | 1 | 16 | 1 - 2 | 2 | 1 | 17 | 1 - 2 | 2 | 1 | 18 | 1 - 2 | 2 | 1 | 19 | 1 - 2 | 2 | 1 | | 10 - 2 | 2 | 2 | 20 | 1 - 2 | 2 | 2 | 21 | 1 - 2 | 2 | 2 | 22 | 1 - 2 | 2 | 2 | 23 | 1 - 2 | 2 | 2 | 24 | 1 - 2 | 2 | 2 | 25 | 1 - 2 | 2 | 2 | 26 | 1 - 2 | 2 | 2 | 27 | 1 - 2 | 2 | 2 | 28 | 1 - 2 | 2 | 2 | 29 | 1 - 2 | 2 | 2 | | 10 - 2 | 2 | 3 | 30 | 1 - 2 | 2 | 3 | 31 | 1 - 2 | 2 | 3 | 32 | 1 - 2 | 2 | 3 | 33 | 1 - 2 | 2 | 3 | 34 | 1 - 2 | 2 | 3 | 35 | 1 - 2 | 2 | 3 | 36 | 1 - 2 | 2 | 3 | 37 | 1 - 2 | 2 | 3 | 38 | 1 - 2 | 2 | 3 | 39 | 1 - 2 | 2 | 3 | | 10 - 2 | 2 | 4 | 40 | 1 - 2 | 2 | 4 | | 1 - 2 | 2 | | 1 | 1 - 2 | 2 | | 2 | 1 - 2 | 2 | | 3 | 1 - 2 | 2 | | 4 | 1 - 2 | 2 | | 5 | 1 - 2 | 2 | | 6 | 1 - 2 | 2 | | 7 | 1 - 2 | 2 | | 8 | 1 - 2 | 2 | | 9 | 1 - 2 | 2 | | 10 | 1 - 2 | 2 | | 11 | 1 - 2 | 2 | | 12 | 1 - 2 | 2 | | 13 | 1 - 2 | 2 | | 14 | 1 - 2 | 2 | | 15 | 1 - 2 | 2 | | 16 | 1 - 2 | 2 | | 17 | 1 - 2 | 2 | | 18 | 1 - 2 | 2 | | 19 | 1 - 2 | 2 | | 20 | 1 - 2 | 2 | | 21 | 1 - 2 | 2 | | 22 | 1 - 2 | 2 | | 23 | 1 - 2 | 2 | | 24 | 1 - 2 | 2 | | 25 | 1 - 2 | 2 | | 26 | 1 - 2 | 2 | | 27 | 1 - 2 | 2 | | 28 | 1 - 2 | 2 | | 29 | 1 - 2 | 2 | | 30 | 1 - 2 | 2 | | 31 | 1 - 2 | 2 | | 32 | 1 - 2 | 2 | | 33 | 1 - 2 | 2 | | 34 | 1 - 2 | 2 | | 35 | 1 - 2 | 2 | | 36 | 1 - 2 | 2 | | 37 | 1 - 2 | 2 | | 38 | 1 - 2 | 2 | | 39 | 1 - 2 | 2 | | 40 | 1 - 2 | 2 | | | 40 -(172 rows) - --- --- Compare results between plans using sorting and plans using hash --- aggregation. Force spilling in both cases by setting work_mem low --- and altering the statistics. --- -create table gs_data_1 as -select g%1000 as g1000, g%100 as g100, g%10 as g10, g - from generate_series(0,1999) g; -analyze gs_data_1; -alter table gs_data_1 set (autovacuum_enabled = 'false'); -update pg_class set reltuples = 10 where relname='gs_data_1'; -set work_mem='64kB'; --- Produce results with sorting. -set enable_sort = true; -set enable_hashagg = false; -set jit_above_cost = 0; -explain (costs off) -select g100, g10, sum(g::numeric), count(*), max(g::text) -from gs_data_1 group by cube (g1000, g100,g10); - QUERY PLAN ------------------------------------- - GroupAggregate - Group Key: g1000, g100, g10 - Group Key: g1000, g100 - Group Key: g1000 - Group Key: () - Sort Key: g100, g10 - Group Key: g100, g10 - Group Key: g100 - Sort Key: g10, g1000 - Group Key: g10, g1000 - Group Key: g10 - -> Sort - Sort Key: g1000, g100, g10 - -> Seq Scan on gs_data_1 -(14 rows) - -create table gs_group_1 as -select g100, g10, sum(g::numeric), count(*), max(g::text) -from gs_data_1 group by cube (g1000, g100,g10); --- Produce results with hash aggregation. -set enable_hashagg = true; -set enable_sort = false; -explain (costs off) -select g100, g10, sum(g::numeric), count(*), max(g::text) -from gs_data_1 group by cube (g1000, g100,g10); - QUERY PLAN ------------------------------- - MixedAggregate - Hash Key: g1000, g100, g10 - Hash Key: g1000, g100 - Hash Key: g1000 - Hash Key: g100, g10 - Hash Key: g100 - Hash Key: g10, g1000 - Hash Key: g10 - Group Key: () - -> Seq Scan on gs_data_1 -(10 rows) - -create table gs_hash_1 as -select g100, g10, sum(g::numeric), count(*), max(g::text) -from gs_data_1 group by cube (g1000, g100,g10); -set enable_sort = true; -set work_mem to default; --- Compare results -(select * from gs_hash_1 except select * from gs_group_1) - union all -(select * from gs_group_1 except select * from gs_hash_1); - g100 | g10 | sum | count | max -------+-----+-----+-------+----- -(0 rows) - -drop table gs_group_1; -drop table gs_hash_1; --- end +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/join_hash.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/join_hash.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/join_hash.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/join_hash.out 2022-02-13 01:12:18.165507495 +0100 @@ -555,461 +555,8 @@ select count(*) from join_foo left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Hash - -> Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; --- single-batch with rescan, parallel-oblivious -savepoint settings; -set enable_parallel_hash = off; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Hash - -> Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - f -(1 row) - -rollback to settings; --- multi-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '64kB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Parallel Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Parallel Hash - -> Parallel Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; --- single-batch with rescan, parallel-aware -savepoint settings; -set enable_parallel_hash = on; -set parallel_leader_participation = off; -set min_parallel_table_scan_size = 0; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -set enable_material = off; -set enable_mergejoin = off; -set work_mem = '4MB'; -explain (costs off) - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: ((join_foo.id < (b1.id + 1)) AND (join_foo.id > (b1.id - 1))) - -> Seq Scan on join_foo - -> Gather - Workers Planned: 2 - -> Parallel Hash Join - Hash Cond: (b1.id = b2.id) - -> Parallel Seq Scan on join_bar b1 - -> Parallel Hash - -> Parallel Seq Scan on join_bar b2 -(11 rows) - -select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; - count -------- - 3 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select count(*) from join_foo - left join (select b1.id, b1.t from join_bar b1 join join_bar b2 using (id)) ss - on join_foo.id < ss.id + 1 and join_foo.id > ss.id - 1; -$$); - multibatch ------------- - f -(1 row) - -rollback to settings; --- A full outer join where every record is matched. --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r full outer join simple s using (id); - count -------- - 20000 -(1 row) - -rollback to settings; --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s using (id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: (r.id = s.id) - -> Seq Scan on simple r - -> Hash - -> Seq Scan on simple s -(6 rows) - -select count(*) from simple r full outer join simple s using (id); - count -------- - 20000 -(1 row) - -rollback to settings; --- An full outer join where every record is not matched. --- non-parallel -savepoint settings; -set local max_parallel_workers_per_gather = 0; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: ((0 - s.id) = r.id) - -> Seq Scan on simple s - -> Hash - -> Seq Scan on simple r -(6 rows) - -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - count -------- - 40000 -(1 row) - -rollback to settings; --- parallelism not possible with parallel-oblivious outer hash join -savepoint settings; -set local max_parallel_workers_per_gather = 2; -explain (costs off) - select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - QUERY PLAN ----------------------------------------- - Aggregate - -> Hash Full Join - Hash Cond: ((0 - s.id) = r.id) - -> Seq Scan on simple s - -> Hash - -> Seq Scan on simple r -(6 rows) - -select count(*) from simple r full outer join simple s on (r.id = 0 - s.id); - count -------- - 40000 -(1 row) - -rollback to settings; --- exercise special code paths for huge tuples (note use of non-strict --- expression and left join required to get the detoasted tuple into --- the hash table) --- parallel with parallel-aware hash join (hits ExecParallelHashLoadTuple and --- sts_puttuple oversized tuple cases because it's multi-batch) -savepoint settings; -set max_parallel_workers_per_gather = 2; -set enable_parallel_hash = on; -set work_mem = '128kB'; -explain (costs off) - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); - QUERY PLAN ----------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Hash Left Join - Hash Cond: (wide.id = wide_1.id) - -> Parallel Seq Scan on wide - -> Parallel Hash - -> Parallel Seq Scan on wide wide_1 -(9 rows) - -select length(max(s.t)) -from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); - length --------- - 320000 -(1 row) - -select final > 1 as multibatch - from hash_join_batches( -$$ - select length(max(s.t)) - from wide left join (select id, coalesce(t, '') || '' as t from wide) s using (id); -$$); - multibatch ------------- - t -(1 row) - -rollback to settings; -rollback; --- Verify that hash key expressions reference the correct --- nodes. Hashjoin's hashkeys need to reference its outer plan, Hash's --- need to reference Hash's outer plan (which is below HashJoin's --- inner plan). It's not trivial to verify that the references are --- correct (we don't display the hashkeys themselves), but if the --- hashkeys contain subplan references, those will be displayed. Force --- subplans to appear just about everywhere. --- --- Bug report: --- https://www.postgresql.org/message-id/CAPpHfdvGVegF_TKKRiBrSmatJL2dR9uwFCuR%2BteQ_8tEXU8mxg%40mail.gmail.com --- -BEGIN; -SET LOCAL enable_sort = OFF; -- avoid mergejoins -SET LOCAL from_collapse_limit = 1; -- allows easy changing of join order -CREATE TABLE hjtest_1 (a text, b int, id int, c bool); -CREATE TABLE hjtest_2 (a bool, id int, b text, c int); -INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 2, 1, false); -- matches -INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 2, false); -- fails id join condition -INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 20, 1, false); -- fails < 50 -INSERT INTO hjtest_1(a, b, id, c) VALUES ('text', 1, 1, false); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) -INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 2); -- matches -INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 3, 'another', 7); -- fails id join condition -INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 90); -- fails < 55 -INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'another', 3); -- fails (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) -INSERT INTO hjtest_2(a, id, b, c) VALUES (true, 1, 'text', 1); -- fails hjtest_1.a <> hjtest_2.b; -EXPLAIN (COSTS OFF, VERBOSE) -SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 -FROM hjtest_1, hjtest_2 -WHERE - hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) - AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) - AND (SELECT hjtest_1.b * 5) < 50 - AND (SELECT hjtest_2.c * 5) < 55 - AND hjtest_1.a <> hjtest_2.b; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Hash Join - Output: hjtest_1.a, hjtest_2.a, (hjtest_1.tableoid)::regclass, (hjtest_2.tableoid)::regclass - Hash Cond: ((hjtest_1.id = (SubPlan 1)) AND ((SubPlan 2) = (SubPlan 3))) - Join Filter: (hjtest_1.a <> hjtest_2.b) - -> Seq Scan on public.hjtest_1 - Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b - Filter: ((SubPlan 4) < 50) - SubPlan 4 - -> Result - Output: (hjtest_1.b * 5) - -> Hash - Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b - -> Seq Scan on public.hjtest_2 - Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b - Filter: ((SubPlan 5) < 55) - SubPlan 5 - -> Result - Output: (hjtest_2.c * 5) - SubPlan 1 - -> Result - Output: 1 - One-Time Filter: (hjtest_2.id = 1) - SubPlan 3 - -> Result - Output: (hjtest_2.c * 5) - SubPlan 2 - -> Result - Output: (hjtest_1.b * 5) -(28 rows) - -SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 -FROM hjtest_1, hjtest_2 -WHERE - hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) - AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) - AND (SELECT hjtest_1.b * 5) < 50 - AND (SELECT hjtest_2.c * 5) < 55 - AND hjtest_1.a <> hjtest_2.b; - a1 | a2 | t1 | t2 -------+----+----------+---------- - text | t | hjtest_1 | hjtest_2 -(1 row) - -EXPLAIN (COSTS OFF, VERBOSE) -SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 -FROM hjtest_2, hjtest_1 -WHERE - hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) - AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) - AND (SELECT hjtest_1.b * 5) < 50 - AND (SELECT hjtest_2.c * 5) < 55 - AND hjtest_1.a <> hjtest_2.b; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Hash Join - Output: hjtest_1.a, hjtest_2.a, (hjtest_1.tableoid)::regclass, (hjtest_2.tableoid)::regclass - Hash Cond: (((SubPlan 1) = hjtest_1.id) AND ((SubPlan 3) = (SubPlan 2))) - Join Filter: (hjtest_1.a <> hjtest_2.b) - -> Seq Scan on public.hjtest_2 - Output: hjtest_2.a, hjtest_2.tableoid, hjtest_2.id, hjtest_2.c, hjtest_2.b - Filter: ((SubPlan 5) < 55) - SubPlan 5 - -> Result - Output: (hjtest_2.c * 5) - -> Hash - Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b - -> Seq Scan on public.hjtest_1 - Output: hjtest_1.a, hjtest_1.tableoid, hjtest_1.id, hjtest_1.b - Filter: ((SubPlan 4) < 50) - SubPlan 4 - -> Result - Output: (hjtest_1.b * 5) - SubPlan 2 - -> Result - Output: (hjtest_1.b * 5) - SubPlan 1 - -> Result - Output: 1 - One-Time Filter: (hjtest_2.id = 1) - SubPlan 3 - -> Result - Output: (hjtest_2.c * 5) -(28 rows) - -SELECT hjtest_1.a a1, hjtest_2.a a2,hjtest_1.tableoid::regclass t1, hjtest_2.tableoid::regclass t2 -FROM hjtest_2, hjtest_1 -WHERE - hjtest_1.id = (SELECT 1 WHERE hjtest_2.id = 1) - AND (SELECT hjtest_1.b * 5) = (SELECT hjtest_2.c*5) - AND (SELECT hjtest_1.b * 5) < 50 - AND (SELECT hjtest_2.c * 5) < 55 - AND hjtest_1.a <> hjtest_2.b; - a1 | a2 | t1 | t2 -------+----+----------+---------- - text | t | hjtest_1 | hjtest_2 -(1 row) - -ROLLBACK; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/misc.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/misc.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/misc.out 2022-02-13 01:11:52.138796905 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/misc.out 2022-02-13 01:13:13.182267010 +0100 @@ -508,185 +508,8 @@ -- everyone else is fine. -- SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM ONLY person p; - name | name | name --------+-------------+--------------- - mike | posthacking | advil - mike | posthacking | peet's coffee - joe | basketball | hightops - sally | basketball | hightops -(4 rows) - --- --- as above, but jeff needs advil and peet's coffee as well. --- -SELECT p.name, name(p.hobbies), name(equipment(p.hobbies)) FROM person* p; - name | name | name --------+-------------+--------------- - mike | posthacking | advil - mike | posthacking | peet's coffee - joe | basketball | hightops - sally | basketball | hightops - jeff | posthacking | advil - jeff | posthacking | peet's coffee -(6 rows) - --- --- just like the last two, but make sure that the target list fixup and --- unflattening is being done correctly. --- -SELECT name(equipment(p.hobbies)), p.name, name(p.hobbies) FROM ONLY person p; - name | name | name ----------------+-------+------------- - advil | mike | posthacking - peet's coffee | mike | posthacking - hightops | joe | basketball - hightops | sally | basketball -(4 rows) - -SELECT (p.hobbies).equipment.name, p.name, name(p.hobbies) FROM person* p; - name | name | name ----------------+-------+------------- - advil | mike | posthacking - peet's coffee | mike | posthacking - hightops | joe | basketball - hightops | sally | basketball - advil | jeff | posthacking - peet's coffee | jeff | posthacking -(6 rows) - -SELECT (p.hobbies).equipment.name, name(p.hobbies), p.name FROM ONLY person p; - name | name | name ----------------+-------------+------- - advil | posthacking | mike - peet's coffee | posthacking | mike - hightops | basketball | joe - hightops | basketball | sally -(4 rows) - -SELECT name(equipment(p.hobbies)), name(p.hobbies), p.name FROM person* p; - name | name | name ----------------+-------------+------- - advil | posthacking | mike - peet's coffee | posthacking | mike - hightops | basketball | joe - hightops | basketball | sally - advil | posthacking | jeff - peet's coffee | posthacking | jeff -(6 rows) - -SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1a(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1b(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_1c(hobby_construct_named(text 'skywalking', text 'mer'))); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_2a(text 'skywalking')); - name ------- - guts -(1 row) - -SELECT name(equipment_named_ambiguous_2b(text 'skywalking')); - name ---------------- - advil - peet's coffee - hightops - guts -(4 rows) - -SELECT hobbies_by_name('basketball'); - hobbies_by_name ------------------ - joe -(1 row) - -SELECT name, overpaid(emp.*) FROM emp; - name | overpaid ---------+---------- - sharon | t - sam | t - bill | t - jeff | f - cim | f - linda | f -(6 rows) - --- --- Try a few cases with SQL-spec row constructor expressions --- -SELECT * FROM equipment(ROW('skywalking', 'mer')); - name | hobby -------+------------ - guts | skywalking -(1 row) - -SELECT name(equipment(ROW('skywalking', 'mer'))); - name ------- - guts -(1 row) - -SELECT *, name(equipment(h.*)) FROM hobbies_r h; - name | person | name --------------+--------+--------------- - posthacking | mike | advil - posthacking | mike | peet's coffee - posthacking | jeff | advil - posthacking | jeff | peet's coffee - basketball | joe | hightops - basketball | sally | hightops - skywalking | | guts -(7 rows) - -SELECT *, (equipment(CAST((h.*) AS hobbies_r))).name FROM hobbies_r h; - name | person | name --------------+--------+--------------- - posthacking | mike | advil - posthacking | mike | peet's coffee - posthacking | jeff | advil - posthacking | jeff | peet's coffee - basketball | joe | hightops - basketball | sally | hightops - skywalking | | guts -(7 rows) - --- --- functional joins --- --- --- instance rules --- --- --- rewrite rules --- +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/collate.icu.utf8_1.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/collate.icu.utf8.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/collate.icu.utf8_1.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/collate.icu.utf8.out 2022-02-13 01:13:13.225600416 +0100 @@ -7,3 +7,1389 @@ AS skip_test \gset \if :skip_test \quit +\endif +SET client_encoding TO UTF8; +CREATE SCHEMA collate_tests; +ERROR: schema "collate_tests" already exists +SET search_path = collate_tests; +CREATE TABLE collate_test1 ( + a int, + b text COLLATE "en-x-icu" NOT NULL +); +ERROR: relation "collate_test1" already exists +\d collate_test1 + Table "collate_tests.collate_test1" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | text | C | not null | +Indexes: + "collate_test1_idx1" btree (b) + "collate_test1_idx2" btree (b COLLATE "POSIX") + "collate_test1_idx3" btree (b COLLATE "POSIX") + "collate_test1_idx4" btree ((b || 'foo'::text) COLLATE "POSIX") + +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "ja_JP.eucjp-x-icu" +); +ERROR: collation "ja_JP.eucjp-x-icu" for encoding "UTF8" does not exist +LINE 3: b text COLLATE "ja_JP.eucjp-x-icu" + ^ +CREATE TABLE collate_test_fail ( + a int, + b text COLLATE "foo-x-icu" +); +ERROR: collation "foo-x-icu" for encoding "UTF8" does not exist +LINE 3: b text COLLATE "foo-x-icu" + ^ +CREATE TABLE collate_test_fail ( + a int COLLATE "en-x-icu", + b text +); +ERROR: collations are not supported by type integer +LINE 2: a int COLLATE "en-x-icu", + ^ +CREATE TABLE collate_test_like ( + LIKE collate_test1 +); +ERROR: relation "collate_test_like" already exists +\d collate_test_like + Table "collate_tests.collate_test_like" + Column | Type | Collation | Nullable | Default +--------+---------+-----------+----------+--------- + a | integer | | | + b | text | C | not null | + +CREATE TABLE collate_test2 ( + a int, + b text COLLATE "sv-x-icu" +); +ERROR: relation "collate_test2" already exists +CREATE TABLE collate_test3 ( + a int, + b text COLLATE "C" +); +INSERT INTO collate_test1 VALUES (1, 'abc'), (2, 'äbc'), (3, 'bbc'), (4, 'ABC'); +INSERT INTO collate_test2 SELECT * FROM collate_test1; +INSERT INTO collate_test3 SELECT * FROM collate_test1; +SELECT * FROM collate_test1 WHERE b >= 'bbc'; + a | b +---+----- + 3 | bbc + 2 | äbc + 3 | bbc +(3 rows) + +SELECT * FROM collate_test2 WHERE b >= 'bbc'; + a | b +---+----- + 3 | bbc + 3 | bbc + 2 | äbc + 3 | bbc +(4 rows) + +SELECT * FROM collate_test3 WHERE b >= 'bbc'; + a | b +---+----- + 3 | bbc + 2 | äbc + 3 | bbc +(3 rows) + +SELECT * FROM collate_test3 WHERE b >= 'BBC'; + a | b +---+----- + 1 | abc + 3 | bbc + 1 | abc + 2 | äbc + 3 | bbc +(5 rows) + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; + a | b +---+----- + 3 | bbc + 2 | äbc + 3 | bbc +(3 rows) + +SELECT * FROM collate_test1 WHERE b >= 'bbc' COLLATE "C"; + a | b +---+----- + 3 | bbc + 2 | äbc + 3 | bbc +(3 rows) + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "C"; + a | b +---+----- + 3 | bbc + 2 | äbc + 3 | bbc +(3 rows) + +SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "en-x-icu"; +ERROR: collation mismatch between explicit collations "C" and "en-x-icu" +LINE 1: ...* FROM collate_test1 WHERE b COLLATE "C" >= 'bbc' COLLATE "e... + ^ +CREATE DOMAIN testdomain_sv AS text COLLATE "sv-x-icu"; +CREATE DOMAIN testdomain_i AS int COLLATE "sv-x-icu"; -- fails +ERROR: collations are not supported by type integer +CREATE TABLE collate_test4 ( + a int, + b testdomain_sv +); +ERROR: relation "collate_test4" already exists +INSERT INTO collate_test4 SELECT * FROM collate_test1; +SELECT a, b FROM collate_test4 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +CREATE TABLE collate_test5 ( + a int, + b testdomain_sv COLLATE "en-x-icu" +); +ERROR: relation "collate_test5" already exists +INSERT INTO collate_test5 SELECT * FROM collate_test1; +SELECT a, b FROM collate_test5 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, b FROM collate_test1 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, b FROM collate_test2 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, b FROM collate_test3 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +-- star expansion +SELECT * FROM collate_test1 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT * FROM collate_test2 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT * FROM collate_test3 ORDER BY b; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +-- constant expression folding +SELECT 'bbc' COLLATE "en-x-icu" > 'äbc' COLLATE "en-x-icu" AS "true"; + true +------ + t +(1 row) + +SELECT 'bbc' COLLATE "sv-x-icu" > 'äbc' COLLATE "sv-x-icu" AS "false"; + false +------- + f +(1 row) + +-- upper/lower +CREATE TABLE collate_test10 ( + a int, + x text COLLATE "en-x-icu", + y text COLLATE "tr-x-icu" +); +ERROR: relation "collate_test10" already exists +INSERT INTO collate_test10 VALUES (1, 'hij', 'hij'), (2, 'HIJ', 'HIJ'); +SELECT a, lower(x), lower(y), upper(x), upper(y), initcap(x), initcap(y) FROM collate_test10; + a | lower | lower | upper | upper | initcap | initcap +---+-------+-------+-------+-------+---------+--------- + 1 | hij | hij | HIJ | HIJ | Hij | Hij + 2 | hij | hij | HIJ | HIJ | Hij | Hij + 1 | hij | hij | HIJ | HIJ | Hij | Hij + 2 | hij | hij | HIJ | HIJ | Hij | Hij +(4 rows) + +SELECT a, lower(x COLLATE "C"), lower(y COLLATE "C") FROM collate_test10; + a | lower | lower +---+-------+------- + 1 | hij | hij + 2 | hij | hij + 1 | hij | hij + 2 | hij | hij +(4 rows) + +SELECT a, x, y FROM collate_test10 ORDER BY lower(y), a; + a | x | y +---+-----+----- + 1 | hij | hij + 1 | hij | hij + 2 | HIJ | HIJ + 2 | HIJ | HIJ +(4 rows) + +-- LIKE/ILIKE +SELECT * FROM collate_test1 WHERE b LIKE 'abc'; + a | b +---+----- + 1 | abc + 1 | abc +(2 rows) + +SELECT * FROM collate_test1 WHERE b LIKE 'abc%'; + a | b +---+----- + 1 | abc + 1 | abc +(2 rows) + +SELECT * FROM collate_test1 WHERE b LIKE '%bc%'; + a | b +---+----- + 1 | abc + 2 | Abc + 3 | bbc + 1 | abc + 2 | äbc + 3 | bbc +(6 rows) + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc'; + a | b +---+----- + 1 | abc + 2 | Abc + 1 | abc + 4 | ABC +(4 rows) + +SELECT * FROM collate_test1 WHERE b ILIKE 'abc%'; + a | b +---+----- + 1 | abc + 2 | Abc + 1 | abc + 4 | ABC +(4 rows) + +SELECT * FROM collate_test1 WHERE b ILIKE '%bc%'; + a | b +---+----- + 1 | abc + 2 | Abc + 3 | bbc + 1 | abc + 2 | äbc + 3 | bbc + 4 | ABC +(7 rows) + +SELECT 'Türkiye' COLLATE "en-x-icu" ILIKE '%KI%' AS "true"; + true +------ + t +(1 row) + +SELECT 'Türkiye' COLLATE "tr-x-icu" ILIKE '%KI%' AS "false"; + false +------- + f +(1 row) + +SELECT 'bıt' ILIKE 'BIT' COLLATE "en-x-icu" AS "false"; + false +------- + f +(1 row) + +SELECT 'bıt' ILIKE 'BIT' COLLATE "tr-x-icu" AS "true"; + true +------ + t +(1 row) + +-- The following actually exercises the selectivity estimation for ILIKE. +SELECT relname FROM pg_class WHERE relname ILIKE 'abc%'; + relname +--------- +(0 rows) + +-- regular expressions +SELECT * FROM collate_test1 WHERE b ~ '^abc$'; + a | b +---+----- + 1 | abc + 1 | abc +(2 rows) + +SELECT * FROM collate_test1 WHERE b ~ '^abc'; + a | b +---+----- + 1 | abc + 1 | abc +(2 rows) + +SELECT * FROM collate_test1 WHERE b ~ 'bc'; + a | b +---+----- + 1 | abc + 2 | Abc + 3 | bbc + 1 | abc + 2 | äbc + 3 | bbc +(6 rows) + +SELECT * FROM collate_test1 WHERE b ~* '^abc$'; + a | b +---+----- + 1 | abc + 2 | Abc + 1 | abc + 4 | ABC +(4 rows) + +SELECT * FROM collate_test1 WHERE b ~* '^abc'; + a | b +---+----- + 1 | abc + 2 | Abc + 1 | abc + 4 | ABC +(4 rows) + +SELECT * FROM collate_test1 WHERE b ~* 'bc'; + a | b +---+----- + 1 | abc + 2 | Abc + 3 | bbc + 1 | abc + 2 | äbc + 3 | bbc + 4 | ABC +(7 rows) + +CREATE TABLE collate_test6 ( + a int, + b text COLLATE "en-x-icu" +); +INSERT INTO collate_test6 VALUES (1, 'abc'), (2, 'ABC'), (3, '123'), (4, 'ab1'), + (5, 'a1!'), (6, 'a c'), (7, '!.;'), (8, ' '), + (9, 'äbç'), (10, 'ÄBÇ'); +SELECT b, + b ~ '^[[:alpha:]]+$' AS is_alpha, + b ~ '^[[:upper:]]+$' AS is_upper, + b ~ '^[[:lower:]]+$' AS is_lower, + b ~ '^[[:digit:]]+$' AS is_digit, + b ~ '^[[:alnum:]]+$' AS is_alnum, + b ~ '^[[:graph:]]+$' AS is_graph, + b ~ '^[[:print:]]+$' AS is_print, + b ~ '^[[:punct:]]+$' AS is_punct, + b ~ '^[[:space:]]+$' AS is_space +FROM collate_test6; + b | is_alpha | is_upper | is_lower | is_digit | is_alnum | is_graph | is_print | is_punct | is_space +-----+----------+----------+----------+----------+----------+----------+----------+----------+---------- + abc | t | f | t | f | t | t | t | f | f + ABC | t | t | f | f | t | t | t | f | f + 123 | f | f | f | t | t | t | t | f | f + ab1 | f | f | f | f | t | t | t | f | f + a1! | f | f | f | f | f | t | t | f | f + a c | f | f | f | f | f | f | t | f | f + !.; | f | f | f | f | f | t | t | t | f + | f | f | f | f | f | f | t | f | t + äbç | t | f | t | f | t | t | t | f | f + ÄBÇ | t | t | f | f | t | t | t | f | f +(10 rows) + +SELECT 'Türkiye' COLLATE "en-x-icu" ~* 'KI' AS "true"; + true +------ + t +(1 row) + +SELECT 'Türkiye' COLLATE "tr-x-icu" ~* 'KI' AS "true"; -- true with ICU + true +------ + t +(1 row) + +SELECT 'bıt' ~* 'BIT' COLLATE "en-x-icu" AS "false"; + false +------- + f +(1 row) + +SELECT 'bıt' ~* 'BIT' COLLATE "tr-x-icu" AS "false"; -- false with ICU + false +------- + f +(1 row) + +-- The following actually exercises the selectivity estimation for ~*. +SELECT relname FROM pg_class WHERE relname ~* '^abc'; + relname +--------- +(0 rows) + +/* not run by default because it requires tr_TR system locale +-- to_char + +SET lc_time TO 'tr_TR'; +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY'); +SELECT to_char(date '2010-04-01', 'DD TMMON YYYY' COLLATE "tr-x-icu"); +*/ +-- backwards parsing +CREATE VIEW collview1 AS SELECT * FROM collate_test1 WHERE b COLLATE "C" >= 'bbc'; +ERROR: relation "collview1" already exists +CREATE VIEW collview2 AS SELECT a, b FROM collate_test1 ORDER BY b COLLATE "C"; +ERROR: relation "collview2" already exists +CREATE VIEW collview3 AS SELECT a, lower((x || x) COLLATE "C") FROM collate_test10; +ERROR: relation "collview3" already exists +SELECT table_name, view_definition FROM information_schema.views + WHERE table_name LIKE 'collview%' ORDER BY 1; + table_name | view_definition +------------+------------------------------------------------------------------------------ + collview1 | SELECT collate_test1.a, + + | collate_test1.b + + | FROM collate_test1 + + | WHERE ((collate_test1.b COLLATE "C") >= 'bbc'::text); + collview2 | SELECT collate_test1.a, + + | collate_test1.b + + | FROM collate_test1 + + | ORDER BY (collate_test1.b COLLATE "C"); + collview3 | SELECT collate_test10.a, + + | lower(((collate_test10.x || collate_test10.x) COLLATE "POSIX")) AS lower+ + | FROM collate_test10; +(3 rows) + +-- collation propagation in various expression types +SELECT a, coalesce(b, 'foo') FROM collate_test1 ORDER BY 2; + a | coalesce +---+---------- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, coalesce(b, 'foo') FROM collate_test2 ORDER BY 2; + a | coalesce +---+---------- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, coalesce(b, 'foo') FROM collate_test3 ORDER BY 2; + a | coalesce +---+---------- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, lower(coalesce(x, 'foo')), lower(coalesce(y, 'foo')) FROM collate_test10; + a | lower | lower +---+-------+------- + 1 | hij | hij + 2 | hij | hij + 1 | hij | hij + 2 | hij | hij +(4 rows) + +SELECT a, b, greatest(b, 'CCC') FROM collate_test1 ORDER BY 3; + a | b | greatest +---+-----+---------- + 4 | ABD | CCC + 2 | Abc | CCC + 4 | ABC | CCC + 1 | abc | abc + 1 | abc | abc + 3 | bbc | bbc + 3 | bbc | bbc + 2 | äbc | äbc +(8 rows) + +SELECT a, b, greatest(b, 'CCC') FROM collate_test2 ORDER BY 3; + a | b | greatest +---+-----+---------- + 2 | Abc | CCC + 4 | ABD | CCC + 4 | ABC | CCC + 4 | ABD | CCC + 2 | Abc | CCC + 1 | abc | abc + 1 | abc | abc + 1 | abc | abc + 3 | bbc | bbc + 3 | bbc | bbc + 3 | bbc | bbc + 2 | äbc | äbc +(12 rows) + +SELECT a, b, greatest(b, 'CCC') FROM collate_test3 ORDER BY 3; + a | b | greatest +---+-----+---------- + 4 | ABD | CCC + 2 | Abc | CCC + 4 | ABC | CCC + 1 | abc | abc + 1 | abc | abc + 3 | bbc | bbc + 3 | bbc | bbc + 2 | äbc | äbc +(8 rows) + +SELECT a, x, y, lower(greatest(x, 'foo')), lower(greatest(y, 'foo')) FROM collate_test10; + a | x | y | lower | lower +---+-----+-----+-------+------- + 1 | hij | hij | hij | hij + 2 | HIJ | HIJ | foo | foo + 1 | hij | hij | hij | hij + 2 | HIJ | HIJ | foo | foo +(4 rows) + +SELECT a, nullif(b, 'abc') FROM collate_test1 ORDER BY 2; + a | nullif +---+-------- + 4 | ABC + 4 | ABD + 2 | Abc + 3 | bbc + 3 | bbc + 2 | äbc + 1 | + 1 | +(8 rows) + +SELECT a, nullif(b, 'abc') FROM collate_test2 ORDER BY 2; + a | nullif +---+-------- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc + 1 | + 1 | + 1 | +(12 rows) + +SELECT a, nullif(b, 'abc') FROM collate_test3 ORDER BY 2; + a | nullif +---+-------- + 4 | ABC + 4 | ABD + 2 | Abc + 3 | bbc + 3 | bbc + 2 | äbc + 1 | + 1 | +(8 rows) + +SELECT a, lower(nullif(x, 'foo')), lower(nullif(y, 'foo')) FROM collate_test10; + a | lower | lower +---+-------+------- + 1 | hij | hij + 2 | hij | hij + 1 | hij | hij + 2 | hij | hij +(4 rows) + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test1 ORDER BY 2; + a | b +---+------ + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abcd + 1 | abcd + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test2 ORDER BY 2; + a | b +---+------ + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abcd + 1 | abcd + 1 | abcd + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, CASE b WHEN 'abc' THEN 'abcd' ELSE b END FROM collate_test3 ORDER BY 2; + a | b +---+------ + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abcd + 1 | abcd + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +CREATE DOMAIN testdomain AS text; +ERROR: type "testdomain" already exists +SELECT a, b::testdomain FROM collate_test1 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, b::testdomain FROM collate_test2 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, b::testdomain FROM collate_test3 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, b::testdomain_sv FROM collate_test3 ORDER BY 2; + a | b +---+----- + 1 | abc + 1 | abc + 2 | Abc + 4 | ABC + 4 | ABD + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, lower(x::testdomain), lower(y::testdomain) FROM collate_test10; + a | lower | lower +---+-------+------- + 1 | hij | hij + 2 | hij | hij + 1 | hij | hij + 2 | hij | hij +(4 rows) + +SELECT min(b), max(b) FROM collate_test1; + min | max +-----+----- + ABC | äbc +(1 row) + +SELECT min(b), max(b) FROM collate_test2; + min | max +-----+----- + ABC | äbc +(1 row) + +SELECT min(b), max(b) FROM collate_test3; + min | max +-----+----- + ABC | äbc +(1 row) + +SELECT array_agg(b ORDER BY b) FROM collate_test1; + array_agg +----------------------------------- + {ABC,ABD,Abc,abc,abc,bbc,bbc,äbc} +(1 row) + +SELECT array_agg(b ORDER BY b) FROM collate_test2; + array_agg +--------------------------------------------------- + {ABC,ABD,ABD,Abc,Abc,abc,abc,abc,bbc,bbc,bbc,äbc} +(1 row) + +SELECT array_agg(b ORDER BY b) FROM collate_test3; + array_agg +----------------------------------- + {ABC,ABD,Abc,abc,abc,bbc,bbc,äbc} +(1 row) + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test1 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc + 2 | äbc +(16 rows) + +SELECT a, b FROM collate_test2 UNION SELECT a, b FROM collate_test2 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 3 | bbc + 2 | äbc +(6 rows) + +SELECT a, b FROM collate_test3 WHERE a < 4 INTERSECT SELECT a, b FROM collate_test3 WHERE a > 1 ORDER BY 2; + a | b +---+----- + 2 | Abc + 3 | bbc + 2 | äbc +(3 rows) + +SELECT a, b FROM collate_test3 EXCEPT SELECT a, b FROM collate_test3 WHERE a < 2 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 3 | bbc + 2 | äbc +(5 rows) + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3 ORDER BY 2; -- fail + a | b +---+----- + 4 | ABC + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc + 2 | äbc +(16 rows) + +SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; -- ok + a | b +---+----- + 1 | abc + 2 | Abc + 3 | bbc + 4 | ABD + 1 | abc + 2 | äbc + 3 | bbc + 4 | ABC + 1 | abc + 2 | Abc + 3 | bbc + 4 | ABD + 1 | abc + 2 | äbc + 3 | bbc + 4 | ABC +(16 rows) + +SELECT a, b FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; -- fail + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 3 | bbc + 2 | äbc +(6 rows) + +SELECT a, b COLLATE "C" FROM collate_test1 UNION SELECT a, b FROM collate_test3 ORDER BY 2; -- ok + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 3 | bbc + 2 | äbc +(6 rows) + +SELECT a, b FROM collate_test1 INTERSECT SELECT a, b FROM collate_test3 ORDER BY 2; -- fail + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 3 | bbc + 2 | äbc +(6 rows) + +SELECT a, b FROM collate_test1 EXCEPT SELECT a, b FROM collate_test3 ORDER BY 2; -- fail + a | b +---+--- +(0 rows) + +CREATE TABLE test_u AS SELECT a, b FROM collate_test1 UNION ALL SELECT a, b FROM collate_test3; -- fail +-- ideally this would be a parse-time error, but for now it must be run-time: +select x < y from collate_test10; -- fail +ERROR: could not determine which collation to use for string comparison +HINT: Use the COLLATE clause to set the collation explicitly. +select x || y from collate_test10; -- ok, because || is not collation aware + ?column? +---------- + hijhij + HIJHIJ + hijhij + HIJHIJ +(4 rows) + +select x, y from collate_test10 order by x || y; -- not so ok +ERROR: collation mismatch between implicit collations "C" and "POSIX" +LINE 1: select x, y from collate_test10 order by x || y; + ^ +HINT: You can choose the collation by applying the COLLATE clause to one or both expressions. +-- collation mismatch between recursive and non-recursive term +WITH RECURSIVE foo(x) AS + (SELECT x FROM (VALUES('a' COLLATE "en-x-icu"),('b')) t(x) + UNION ALL + SELECT (x || 'c') COLLATE "de-x-icu" FROM foo WHERE length(x) < 10) +SELECT * FROM foo; +ERROR: recursive query "foo" column 1 has collation "en-x-icu" in non-recursive term but collation "de-x-icu" overall +LINE 2: (SELECT x FROM (VALUES('a' COLLATE "en-x-icu"),('b')) t(x... + ^ +HINT: Use the COLLATE clause to set the collation of the non-recursive term. +-- casting +SELECT CAST('42' AS text COLLATE "C"); +ERROR: syntax error at or near "COLLATE" +LINE 1: SELECT CAST('42' AS text COLLATE "C"); + ^ +SELECT a, CAST(b AS varchar) FROM collate_test1 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, CAST(b AS varchar) FROM collate_test2 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, CAST(b AS varchar) FROM collate_test3 ORDER BY 2; + a | b +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +-- propagation of collation in SQL functions (inlined and non-inlined cases) +-- and plpgsql functions too +CREATE FUNCTION mylt (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 $$; +CREATE FUNCTION mylt_noninline (text, text) RETURNS boolean LANGUAGE sql + AS $$ select $1 < $2 limit 1 $$; +CREATE FUNCTION mylt_plpgsql (text, text) RETURNS boolean LANGUAGE plpgsql + AS $$ begin return $1 < $2; end $$; +SELECT a.b AS a, b.b AS b, a.b < b.b AS lt, + mylt(a.b, b.b), mylt_noninline(a.b, b.b), mylt_plpgsql(a.b, b.b) +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + a | b | lt | mylt | mylt_noninline | mylt_plpgsql +-----+-----+----+------+----------------+-------------- + ABC | ABC | f | f | f | f + ABC | ABD | t | t | t | t + ABC | Abc | t | t | t | t + ABC | abc | t | t | t | t + ABC | abc | t | t | t | t + ABC | bbc | t | t | t | t + ABC | bbc | t | t | t | t + ABC | äbc | t | t | t | t + ABD | ABC | f | f | f | f + ABD | ABD | f | f | f | f + ABD | Abc | t | t | t | t + ABD | abc | t | t | t | t + ABD | abc | t | t | t | t + ABD | bbc | t | t | t | t + ABD | bbc | t | t | t | t + ABD | äbc | t | t | t | t + Abc | ABC | f | f | f | f + Abc | ABD | f | f | f | f + Abc | Abc | f | f | f | f + Abc | abc | t | t | t | t + Abc | abc | t | t | t | t + Abc | bbc | t | t | t | t + Abc | bbc | t | t | t | t + Abc | äbc | t | t | t | t + abc | ABC | f | f | f | f + abc | ABC | f | f | f | f + abc | ABD | f | f | f | f + abc | ABD | f | f | f | f + abc | Abc | f | f | f | f + abc | Abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | äbc | t | t | t | t + abc | äbc | t | t | t | t + bbc | ABC | f | f | f | f + bbc | ABC | f | f | f | f + bbc | ABD | f | f | f | f + bbc | ABD | f | f | f | f + bbc | Abc | f | f | f | f + bbc | Abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | äbc | t | t | t | t + bbc | äbc | t | t | t | t + äbc | ABC | f | f | f | f + äbc | ABD | f | f | f | f + äbc | Abc | f | f | f | f + äbc | abc | f | f | f | f + äbc | abc | f | f | f | f + äbc | bbc | f | f | f | f + äbc | bbc | f | f | f | f + äbc | äbc | f | f | f | f +(64 rows) + +SELECT a.b AS a, b.b AS b, a.b < b.b COLLATE "C" AS lt, + mylt(a.b, b.b COLLATE "C"), mylt_noninline(a.b, b.b COLLATE "C"), + mylt_plpgsql(a.b, b.b COLLATE "C") +FROM collate_test1 a, collate_test1 b +ORDER BY a.b, b.b; + a | b | lt | mylt | mylt_noninline | mylt_plpgsql +-----+-----+----+------+----------------+-------------- + ABC | ABC | f | f | f | f + ABC | ABD | t | t | t | t + ABC | Abc | t | t | t | t + ABC | abc | t | t | t | t + ABC | abc | t | t | t | t + ABC | bbc | t | t | t | t + ABC | bbc | t | t | t | t + ABC | äbc | t | t | t | t + ABD | ABC | f | f | f | f + ABD | ABD | f | f | f | f + ABD | Abc | t | t | t | t + ABD | abc | t | t | t | t + ABD | abc | t | t | t | t + ABD | bbc | t | t | t | t + ABD | bbc | t | t | t | t + ABD | äbc | t | t | t | t + Abc | ABC | f | f | f | f + Abc | ABD | f | f | f | f + Abc | Abc | f | f | f | f + Abc | abc | t | t | t | t + Abc | abc | t | t | t | t + Abc | bbc | t | t | t | t + Abc | bbc | t | t | t | t + Abc | äbc | t | t | t | t + abc | ABC | f | f | f | f + abc | ABC | f | f | f | f + abc | ABD | f | f | f | f + abc | ABD | f | f | f | f + abc | Abc | f | f | f | f + abc | Abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | abc | f | f | f | f + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | bbc | t | t | t | t + abc | äbc | t | t | t | t + abc | äbc | t | t | t | t + bbc | ABC | f | f | f | f + bbc | ABC | f | f | f | f + bbc | ABD | f | f | f | f + bbc | ABD | f | f | f | f + bbc | Abc | f | f | f | f + bbc | Abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | abc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | bbc | f | f | f | f + bbc | äbc | t | t | t | t + bbc | äbc | t | t | t | t + äbc | ABC | f | f | f | f + äbc | ABD | f | f | f | f + äbc | Abc | f | f | f | f + äbc | abc | f | f | f | f + äbc | abc | f | f | f | f + äbc | bbc | f | f | f | f + äbc | bbc | f | f | f | f + äbc | äbc | f | f | f | f +(64 rows) + +-- collation override in plpgsql +CREATE FUNCTION mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text := x; + yy text := y; +begin + return xx < yy; +end +$$; +SELECT mylt2('a', 'B' collate "en-x-icu") as t, mylt2('a', 'B' collate "C") as f; + t | f +---+--- + t | f +(1 row) + +CREATE OR REPLACE FUNCTION + mylt2 (x text, y text) RETURNS boolean LANGUAGE plpgsql AS $$ +declare + xx text COLLATE "POSIX" := x; + yy text := y; +begin + return xx < yy; +end +$$; +SELECT mylt2('a', 'B') as f; + f +--- + f +(1 row) + +SELECT mylt2('a', 'B' collate "C") as fail; -- conflicting collations +ERROR: could not determine which collation to use for string comparison +HINT: Use the COLLATE clause to set the collation explicitly. +CONTEXT: PL/pgSQL function mylt2(text,text) line 6 at RETURN +SELECT mylt2('a', 'B' collate "POSIX") as f; + f +--- + f +(1 row) + +-- polymorphism +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test1)) ORDER BY 1; + unnest +-------- + ABC + ABD + Abc + abc + abc + bbc + bbc + äbc +(8 rows) + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test2)) ORDER BY 1; + unnest +-------- + ABC + ABD + ABD + Abc + Abc + abc + abc + abc + bbc + bbc + bbc + äbc +(12 rows) + +SELECT * FROM unnest((SELECT array_agg(b ORDER BY b) FROM collate_test3)) ORDER BY 1; + unnest +-------- + ABC + ABD + Abc + abc + abc + bbc + bbc + äbc +(8 rows) + +CREATE FUNCTION dup (anyelement) RETURNS anyelement + AS 'select $1' LANGUAGE sql; +ERROR: function "dup" already exists with same argument types +SELECT a, dup(b) FROM collate_test1 ORDER BY 2; + a | dup +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +SELECT a, dup(b) FROM collate_test2 ORDER BY 2; + a | dup +---+----- + 4 | ABC + 4 | ABD + 4 | ABD + 2 | Abc + 2 | Abc + 1 | abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 3 | bbc + 2 | äbc +(12 rows) + +SELECT a, dup(b) FROM collate_test3 ORDER BY 2; + a | dup +---+----- + 4 | ABC + 4 | ABD + 2 | Abc + 1 | abc + 1 | abc + 3 | bbc + 3 | bbc + 2 | äbc +(8 rows) + +-- indexes +CREATE INDEX collate_test1_idx1 ON collate_test1 (b); +ERROR: relation "collate_test1_idx1" already exists +CREATE INDEX collate_test1_idx2 ON collate_test1 (b COLLATE "C"); +ERROR: relation "collate_test1_idx2" already exists +CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C")); -- this is different grammatically +ERROR: relation "collate_test1_idx3" already exists +CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX")); +ERROR: relation "collate_test1_idx4" already exists +CREATE INDEX collate_test1_idx5 ON collate_test1 (a COLLATE "C"); -- fail +ERROR: collations are not supported by type integer +CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); -- fail +ERROR: collations are not supported by type integer +LINE 1: ...ATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C... + ^ +SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1; + relname | pg_get_indexdef +--------------------+------------------------------------------------------------------------------------------------------------------- + collate_test1_idx1 | CREATE INDEX collate_test1_idx1 ON collate_tests.collate_test1 USING btree (b) + collate_test1_idx2 | CREATE INDEX collate_test1_idx2 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX") + collate_test1_idx3 | CREATE INDEX collate_test1_idx3 ON collate_tests.collate_test1 USING btree (b COLLATE "POSIX") + collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_tests.collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX") +(4 rows) + +set enable_seqscan = off; +explain (costs off) +select * from collate_test1 where b ilike 'abc'; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/incremental_sort.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/incremental_sort.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/incremental_sort.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/incremental_sort.out 2022-02-13 01:13:13.088933519 +0100 @@ -710,977 +710,8 @@ set local enable_material = off; set local enable_sort = off; explain (costs off) select * from t left join (select * from (select * from t order by a) v order by a, b) s on s.a = t.a where t.a in (1, 2); - QUERY PLAN ------------------------------------------------- - Nested Loop Left Join - Join Filter: (t_1.a = t.a) - -> Seq Scan on t - Filter: (a = ANY ('{1,2}'::integer[])) - -> Incremental Sort - Sort Key: t_1.a, t_1.b - Presorted Key: t_1.a - -> Sort - Sort Key: t_1.a - -> Seq Scan on t t_1 -(10 rows) - -select * from t left join (select * from (select * from t order by a) v order by a, b) s on s.a = t.a where t.a in (1, 2); - a | b | a | b ----+---+---+--- - 1 | 1 | 1 | 1 - 2 | 2 | 2 | 2 -(2 rows) - -rollback; --- Test EXPLAIN ANALYZE with both fullsort and presorted groups. -select explain_analyze_without_memory('select * from (select * from t order by a) s order by a, b limit 70'); - explain_analyze_without_memory ----------------------------------------------------------------------------------------------------------------- - Limit (actual rows=70 loops=1) - -> Incremental Sort (actual rows=70 loops=1) - Sort Key: t.a, t.b - Presorted Key: t.a - Full-sort Groups: 1 Sort Method: quicksort Average Memory: NNkB Peak Memory: NNkB - Pre-sorted Groups: 5 Sort Methods: top-N heapsort, quicksort Average Memory: NNkB Peak Memory: NNkB - -> Sort (actual rows=1000 loops=1) - Sort Key: t.a - Sort Method: quicksort Memory: NNkB - -> Seq Scan on t (actual rows=1000 loops=1) -(10 rows) - -select jsonb_pretty(explain_analyze_inc_sort_nodes_without_memory('select * from (select * from t order by a) s order by a, b limit 70')); - jsonb_pretty -------------------------------------------------- - [ + - { + - "Sort Key": [ + - "t.a", + - "t.b" + - ], + - "Node Type": "Incremental Sort", + - "Actual Rows": 70, + - "Actual Loops": 1, + - "Presorted Key": [ + - "t.a" + - ], + - "Parallel Aware": false, + - "Full-sort Groups": { + - "Group Count": 1, + - "Sort Methods Used": [ + - "quicksort" + - ], + - "Sort Space Memory": { + - "Peak Sort Space Used": "NN", + - "Average Sort Space Used": "NN"+ - } + - }, + - "Pre-sorted Groups": { + - "Group Count": 5, + - "Sort Methods Used": [ + - "top-N heapsort", + - "quicksort" + - ], + - "Sort Space Memory": { + - "Peak Sort Space Used": "NN", + - "Average Sort Space Used": "NN"+ - } + - }, + - "Parent Relationship": "Outer" + - } + - ] -(1 row) - -select explain_analyze_inc_sort_nodes_verify_invariants('select * from (select * from t order by a) s order by a, b limit 70'); - explain_analyze_inc_sort_nodes_verify_invariants --------------------------------------------------- - t -(1 row) - -delete from t; --- Small groups of 10 tuples each tested around each mode transition point. -insert into t(a, b) select i / 10, i from generate_series(1, 1000) n(i); -analyze t; -explain (costs off) select * from (select * from t order by a) s order by a, b limit 31; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 31; - a | b ----+---- - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 5 - 0 | 6 - 0 | 7 - 0 | 8 - 0 | 9 - 1 | 10 - 1 | 11 - 1 | 12 - 1 | 13 - 1 | 14 - 1 | 15 - 1 | 16 - 1 | 17 - 1 | 18 - 1 | 19 - 2 | 20 - 2 | 21 - 2 | 22 - 2 | 23 - 2 | 24 - 2 | 25 - 2 | 26 - 2 | 27 - 2 | 28 - 2 | 29 - 3 | 30 - 3 | 31 -(31 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 32; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 32; - a | b ----+---- - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 5 - 0 | 6 - 0 | 7 - 0 | 8 - 0 | 9 - 1 | 10 - 1 | 11 - 1 | 12 - 1 | 13 - 1 | 14 - 1 | 15 - 1 | 16 - 1 | 17 - 1 | 18 - 1 | 19 - 2 | 20 - 2 | 21 - 2 | 22 - 2 | 23 - 2 | 24 - 2 | 25 - 2 | 26 - 2 | 27 - 2 | 28 - 2 | 29 - 3 | 30 - 3 | 31 - 3 | 32 -(32 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 33; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 33; - a | b ----+---- - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 5 - 0 | 6 - 0 | 7 - 0 | 8 - 0 | 9 - 1 | 10 - 1 | 11 - 1 | 12 - 1 | 13 - 1 | 14 - 1 | 15 - 1 | 16 - 1 | 17 - 1 | 18 - 1 | 19 - 2 | 20 - 2 | 21 - 2 | 22 - 2 | 23 - 2 | 24 - 2 | 25 - 2 | 26 - 2 | 27 - 2 | 28 - 2 | 29 - 3 | 30 - 3 | 31 - 3 | 32 - 3 | 33 -(33 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 65; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 65; - a | b ----+---- - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 5 - 0 | 6 - 0 | 7 - 0 | 8 - 0 | 9 - 1 | 10 - 1 | 11 - 1 | 12 - 1 | 13 - 1 | 14 - 1 | 15 - 1 | 16 - 1 | 17 - 1 | 18 - 1 | 19 - 2 | 20 - 2 | 21 - 2 | 22 - 2 | 23 - 2 | 24 - 2 | 25 - 2 | 26 - 2 | 27 - 2 | 28 - 2 | 29 - 3 | 30 - 3 | 31 - 3 | 32 - 3 | 33 - 3 | 34 - 3 | 35 - 3 | 36 - 3 | 37 - 3 | 38 - 3 | 39 - 4 | 40 - 4 | 41 - 4 | 42 - 4 | 43 - 4 | 44 - 4 | 45 - 4 | 46 - 4 | 47 - 4 | 48 - 4 | 49 - 5 | 50 - 5 | 51 - 5 | 52 - 5 | 53 - 5 | 54 - 5 | 55 - 5 | 56 - 5 | 57 - 5 | 58 - 5 | 59 - 6 | 60 - 6 | 61 - 6 | 62 - 6 | 63 - 6 | 64 - 6 | 65 -(65 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 66; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 66; - a | b ----+---- - 0 | 1 - 0 | 2 - 0 | 3 - 0 | 4 - 0 | 5 - 0 | 6 - 0 | 7 - 0 | 8 - 0 | 9 - 1 | 10 - 1 | 11 - 1 | 12 - 1 | 13 - 1 | 14 - 1 | 15 - 1 | 16 - 1 | 17 - 1 | 18 - 1 | 19 - 2 | 20 - 2 | 21 - 2 | 22 - 2 | 23 - 2 | 24 - 2 | 25 - 2 | 26 - 2 | 27 - 2 | 28 - 2 | 29 - 3 | 30 - 3 | 31 - 3 | 32 - 3 | 33 - 3 | 34 - 3 | 35 - 3 | 36 - 3 | 37 - 3 | 38 - 3 | 39 - 4 | 40 - 4 | 41 - 4 | 42 - 4 | 43 - 4 | 44 - 4 | 45 - 4 | 46 - 4 | 47 - 4 | 48 - 4 | 49 - 5 | 50 - 5 | 51 - 5 | 52 - 5 | 53 - 5 | 54 - 5 | 55 - 5 | 56 - 5 | 57 - 5 | 58 - 5 | 59 - 6 | 60 - 6 | 61 - 6 | 62 - 6 | 63 - 6 | 64 - 6 | 65 - 6 | 66 -(66 rows) - -delete from t; --- Small groups of only 1 tuple each tested around each mode transition point. -insert into t(a, b) select i, i from generate_series(1, 1000) n(i); -analyze t; -explain (costs off) select * from (select * from t order by a) s order by a, b limit 31; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 31; - a | b -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 - 11 | 11 - 12 | 12 - 13 | 13 - 14 | 14 - 15 | 15 - 16 | 16 - 17 | 17 - 18 | 18 - 19 | 19 - 20 | 20 - 21 | 21 - 22 | 22 - 23 | 23 - 24 | 24 - 25 | 25 - 26 | 26 - 27 | 27 - 28 | 28 - 29 | 29 - 30 | 30 - 31 | 31 -(31 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 32; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 32; - a | b -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 - 11 | 11 - 12 | 12 - 13 | 13 - 14 | 14 - 15 | 15 - 16 | 16 - 17 | 17 - 18 | 18 - 19 | 19 - 20 | 20 - 21 | 21 - 22 | 22 - 23 | 23 - 24 | 24 - 25 | 25 - 26 | 26 - 27 | 27 - 28 | 28 - 29 | 29 - 30 | 30 - 31 | 31 - 32 | 32 -(32 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 33; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 33; - a | b -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 - 11 | 11 - 12 | 12 - 13 | 13 - 14 | 14 - 15 | 15 - 16 | 16 - 17 | 17 - 18 | 18 - 19 | 19 - 20 | 20 - 21 | 21 - 22 | 22 - 23 | 23 - 24 | 24 - 25 | 25 - 26 | 26 - 27 | 27 - 28 | 28 - 29 | 29 - 30 | 30 - 31 | 31 - 32 | 32 - 33 | 33 -(33 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 65; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 65; - a | b -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 - 11 | 11 - 12 | 12 - 13 | 13 - 14 | 14 - 15 | 15 - 16 | 16 - 17 | 17 - 18 | 18 - 19 | 19 - 20 | 20 - 21 | 21 - 22 | 22 - 23 | 23 - 24 | 24 - 25 | 25 - 26 | 26 - 27 | 27 - 28 | 28 - 29 | 29 - 30 | 30 - 31 | 31 - 32 | 32 - 33 | 33 - 34 | 34 - 35 | 35 - 36 | 36 - 37 | 37 - 38 | 38 - 39 | 39 - 40 | 40 - 41 | 41 - 42 | 42 - 43 | 43 - 44 | 44 - 45 | 45 - 46 | 46 - 47 | 47 - 48 | 48 - 49 | 49 - 50 | 50 - 51 | 51 - 52 | 52 - 53 | 53 - 54 | 54 - 55 | 55 - 56 | 56 - 57 | 57 - 58 | 58 - 59 | 59 - 60 | 60 - 61 | 61 - 62 | 62 - 63 | 63 - 64 | 64 - 65 | 65 -(65 rows) - -explain (costs off) select * from (select * from t order by a) s order by a, b limit 66; - QUERY PLAN ---------------------------------- - Limit - -> Incremental Sort - Sort Key: t.a, t.b - Presorted Key: t.a - -> Sort - Sort Key: t.a - -> Seq Scan on t -(7 rows) - -select * from (select * from t order by a) s order by a, b limit 66; - a | b -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 - 10 | 10 - 11 | 11 - 12 | 12 - 13 | 13 - 14 | 14 - 15 | 15 - 16 | 16 - 17 | 17 - 18 | 18 - 19 | 19 - 20 | 20 - 21 | 21 - 22 | 22 - 23 | 23 - 24 | 24 - 25 | 25 - 26 | 26 - 27 | 27 - 28 | 28 - 29 | 29 - 30 | 30 - 31 | 31 - 32 | 32 - 33 | 33 - 34 | 34 - 35 | 35 - 36 | 36 - 37 | 37 - 38 | 38 - 39 | 39 - 40 | 40 - 41 | 41 - 42 | 42 - 43 | 43 - 44 | 44 - 45 | 45 - 46 | 46 - 47 | 47 - 48 | 48 - 49 | 49 - 50 | 50 - 51 | 51 - 52 | 52 - 53 | 53 - 54 | 54 - 55 | 55 - 56 | 56 - 57 | 57 - 58 | 58 - 59 | 59 - 60 | 60 - 61 | 61 - 62 | 62 - 63 | 63 - 64 | 64 - 65 | 65 - 66 | 66 -(66 rows) - -delete from t; -drop table t; --- Incremental sort vs. parallel queries -set min_parallel_table_scan_size = '1kB'; -set min_parallel_index_scan_size = '1kB'; -set parallel_setup_cost = 0; -set parallel_tuple_cost = 0; -set max_parallel_workers_per_gather = 2; -create table t (a int, b int, c int); -insert into t select mod(i,10),mod(i,10),i from generate_series(1,10000) s(i); -create index on t (a); -analyze t; -set enable_incremental_sort = off; -explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1; - QUERY PLAN ------------------------------------------------------- - Limit - -> Sort - Sort Key: a, b, (sum(c)) - -> Finalize HashAggregate - Group Key: a, b - -> Gather - Workers Planned: 2 - -> Partial HashAggregate - Group Key: a, b - -> Parallel Seq Scan on t -(10 rows) - -set enable_incremental_sort = on; -explain (costs off) select a,b,sum(c) from t group by 1,2 order by 1,2,3 limit 1; - QUERY PLAN ----------------------------------------------------------------------- - Limit - -> Incremental Sort - Sort Key: a, b, (sum(c)) - Presorted Key: a, b - -> GroupAggregate - Group Key: a, b - -> Gather Merge - Workers Planned: 2 - -> Incremental Sort - Sort Key: a, b - Presorted Key: a - -> Parallel Index Scan using t_a_idx on t -(12 rows) - --- Incremental sort vs. set operations with varno 0 -set enable_hashagg to off; -explain (costs off) select * from t union select * from t order by 1,3; - QUERY PLAN ----------------------------------------------------------- - Incremental Sort - Sort Key: t.a, t.c - Presorted Key: t.a - -> Unique - -> Sort - Sort Key: t.a, t.b, t.c - -> Append - -> Gather - Workers Planned: 2 - -> Parallel Seq Scan on t - -> Gather - Workers Planned: 2 - -> Parallel Seq Scan on t t_1 -(13 rows) - --- Full sort, not just incremental sort can be pushed below a gather merge path --- by generate_useful_gather_paths. -explain (costs off) select distinct a,b from t; - QUERY PLAN ------------------------------------------- - Unique - -> Gather Merge - Workers Planned: 2 - -> Sort - Sort Key: a, b - -> Parallel Seq Scan on t -(6 rows) - -drop table t; --- Sort pushdown can't go below where expressions are part of the rel target. --- In particular this is interesting for volatile expressions which have to --- go above joins since otherwise we'll incorrectly use expression evaluations --- across multiple rows. -set enable_hashagg=off; -set enable_seqscan=off; -set enable_incremental_sort = off; -set parallel_tuple_cost=0; -set parallel_setup_cost=0; -set min_parallel_table_scan_size = 0; -set min_parallel_index_scan_size = 0; --- Parallel sort below join. -explain (costs off) select distinct sub.unique1, stringu1 -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; - QUERY PLAN --------------------------------------------------------------------------- - Unique - -> Nested Loop - -> Gather Merge - Workers Planned: 2 - -> Sort - Sort Key: tenk1.unique1, tenk1.stringu1 - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(8 rows) - -explain (costs off) select sub.unique1, stringu1 -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub -order by 1, 2; - QUERY PLAN --------------------------------------------------------------------- - Nested Loop - -> Gather Merge - Workers Planned: 2 - -> Sort - Sort Key: tenk1.unique1, tenk1.stringu1 - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(7 rows) - --- Parallel sort but with expression that can be safely generated at the base rel. -explain (costs off) select distinct sub.unique1, md5(stringu1) -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; - QUERY PLAN ----------------------------------------------------------------------------------------- - Unique - -> Nested Loop - -> Gather Merge - Workers Planned: 2 - -> Sort - Sort Key: tenk1.unique1, (md5((tenk1.stringu1)::text)) COLLATE "C" - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(8 rows) - -explain (costs off) select sub.unique1, md5(stringu1) -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub -order by 1, 2; - QUERY PLAN ----------------------------------------------------------------------------------- - Nested Loop - -> Gather Merge - Workers Planned: 2 - -> Sort - Sort Key: tenk1.unique1, (md5((tenk1.stringu1)::text)) COLLATE "C" - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(7 rows) - --- Parallel sort with an aggregate that can be safely generated in parallel, --- but we can't sort by partial aggregate values. -explain (costs off) select count(*) -from tenk1 t1 -join tenk1 t2 on t1.unique1 = t2.unique2 -join tenk1 t3 on t2.unique1 = t3.unique1 -order by count(*); - QUERY PLAN ------------------------------------------------------------------------------------------------ - Sort - Sort Key: (count(*)) - -> Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Hash Join - Hash Cond: (t2.unique1 = t3.unique1) - -> Parallel Hash Join - Hash Cond: (t1.unique1 = t2.unique2) - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 t1 - -> Parallel Hash - -> Parallel Index Scan using tenk1_unique2 on tenk1 t2 - -> Parallel Hash - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 t3 -(15 rows) - --- Parallel sort but with expression (correlated subquery) that --- is prohibited in parallel plans. -explain (costs off) select distinct - unique1, - (select t.unique1 from tenk1 where tenk1.unique1 = t.unique1) -from tenk1 t, generate_series(1, 1000); - QUERY PLAN ---------------------------------------------------------------------------------- - Unique - -> Sort - Sort Key: t.unique1, ((SubPlan 1)) - -> Gather - Workers Planned: 2 - -> Nested Loop - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 t - -> Function Scan on generate_series - SubPlan 1 - -> Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = t.unique1) -(11 rows) - -explain (costs off) select - unique1, - (select t.unique1 from tenk1 where tenk1.unique1 = t.unique1) -from tenk1 t, generate_series(1, 1000) -order by 1, 2; - QUERY PLAN ---------------------------------------------------------------------------- - Sort - Sort Key: t.unique1, ((SubPlan 1)) - -> Gather - Workers Planned: 2 - -> Nested Loop - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 t - -> Function Scan on generate_series - SubPlan 1 - -> Index Only Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = t.unique1) -(10 rows) - --- Parallel sort but with expression not available until the upper rel. -explain (costs off) select distinct sub.unique1, stringu1 || random()::text -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Unique - -> Sort - Sort Key: tenk1.unique1, (((tenk1.stringu1)::text || (random())::text)) COLLATE "C" - -> Gather - Workers Planned: 2 - -> Nested Loop - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(8 rows) - -explain (costs off) select sub.unique1, stringu1 || random()::text -from tenk1, lateral (select tenk1.unique1 from generate_series(1, 1000)) as sub -order by 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------- - Sort - Sort Key: tenk1.unique1, (((tenk1.stringu1)::text || (random())::text)) COLLATE "C" - -> Gather - Workers Planned: 2 - -> Nested Loop - -> Parallel Index Scan using tenk1_unique1 on tenk1 - -> Function Scan on generate_series -(7 rows) - --- Disallow pushing down sort when pathkey is an SRF. -explain (costs off) select unique1 from tenk1 order by unnest('{1,2}'::int[]); - QUERY PLAN -------------------------------------------------------------------------- - Sort - Sort Key: (unnest('{1,2}'::integer[])) - -> Gather - Workers Planned: 2 - -> ProjectSet - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 -(6 rows) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rules.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/rules.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rules.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/rules.out 2022-02-13 01:13:15.228937131 +0100 @@ -2529,6 +2529,14 @@ emp.location, (12 * emp.salary) AS annualsal FROM emp; +upview| SELECT range_parted.a, + range_parted.b, + range_parted.c, + range_parted.d, + range_parted.e + FROM range_parted + WHERE ( SELECT (range_parted.c > (mintab.c1)::numeric) + FROM mintab); SELECT tablename, rulename, definition FROM pg_rules WHERE schemaname IN ('pg_catalog', 'public') ORDER BY tablename, rulename; diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/amutils.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/amutils.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/amutils.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/amutils.out 2022-02-13 01:13:14.388935713 +0100 @@ -93,20 +93,9 @@ 'bogus']::text[]) with ordinality as u(prop,ord) order by ord; - prop | btree | hash | gist | spgist_radix | spgist_quad | gin | brin ---------------------+-------+------+------+--------------+-------------+-----+------ - asc | t | f | f | f | f | f | f - desc | f | f | f | f | f | f | f - nulls_first | f | f | f | f | f | f | f - nulls_last | t | f | f | f | f | f | f - orderable | t | f | f | f | f | f | f - distance_orderable | f | f | t | f | t | f | f - returnable | t | f | f | t | t | f | f - search_array | t | f | f | f | f | f | f - search_nulls | t | f | t | t | t | f | t - bogus | | | | | | | -(10 rows) - +ERROR: relation "hash_i4_index" does not exist +LINE 3: pg_index_column_has_property('hash_i4_index'::regclas... + ^ select prop, pg_index_has_property('onek_hundred'::regclass, prop) as btree, pg_index_has_property('hash_i4_index'::regclass, prop) as hash, @@ -119,15 +108,9 @@ 'bogus']::text[]) with ordinality as u(prop,ord) order by ord; - prop | btree | hash | gist | spgist | gin | brin ----------------+-------+------+------+--------+-----+------ - clusterable | t | f | t | f | f | f - index_scan | t | t | t | t | f | f - bitmap_scan | t | t | t | t | t | t - backward_scan | t | t | f | f | f | f - bogus | | | | | | -(5 rows) - +ERROR: relation "hash_i4_index" does not exist +LINE 3: pg_index_has_property('hash_i4_index'::regclass, prop... + ^ select amname, prop, pg_indexam_has_property(a.oid, prop) as p from pg_am a, unnest(array['can_order', 'can_unique', 'can_multi_col', diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select_parallel.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/select_parallel.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/select_parallel.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/select_parallel.out 2022-02-13 01:13:18.155608736 +0100 @@ -139,1061 +139,8 @@ explain (costs off) select (select max((select pa1.b from part_pa_test pa1 where pa1.a = pa2.a))) from part_pa_test pa2; - QUERY PLAN --------------------------------------------------------------- - Aggregate - -> Gather - Workers Planned: 3 - -> Parallel Append - -> Parallel Seq Scan on part_pa_test_p1 pa2_1 - -> Parallel Seq Scan on part_pa_test_p2 pa2_2 - SubPlan 2 - -> Result - SubPlan 1 - -> Append - -> Seq Scan on part_pa_test_p1 pa1_1 - Filter: (a = pa2.a) - -> Seq Scan on part_pa_test_p2 pa1_2 - Filter: (a = pa2.a) -(14 rows) - -drop table part_pa_test; --- test with leader participation disabled -set parallel_leader_participation = off; -explain (costs off) - select count(*) from tenk1 where stringu1 = 'GRAAAA'; - QUERY PLAN ---------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Seq Scan on tenk1 - Filter: (stringu1 = 'GRAAAA'::name) -(6 rows) - -select count(*) from tenk1 where stringu1 = 'GRAAAA'; - count -------- - 15 -(1 row) - --- test with leader participation disabled, but no workers available (so --- the leader will have to run the plan despite the setting) -set max_parallel_workers = 0; -explain (costs off) - select count(*) from tenk1 where stringu1 = 'GRAAAA'; - QUERY PLAN ---------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Seq Scan on tenk1 - Filter: (stringu1 = 'GRAAAA'::name) -(6 rows) - -select count(*) from tenk1 where stringu1 = 'GRAAAA'; - count -------- - 15 -(1 row) - -reset max_parallel_workers; -reset parallel_leader_participation; --- test that parallel_restricted function doesn't run in worker -alter table tenk1 set (parallel_workers = 4); -explain (verbose, costs off) -select sp_parallel_restricted(unique1) from tenk1 - where stringu1 = 'GRAAAA' order by 1; - QUERY PLAN ---------------------------------------------------------- - Sort - Output: (sp_parallel_restricted(unique1)) - Sort Key: (sp_parallel_restricted(tenk1.unique1)) - -> Gather - Output: sp_parallel_restricted(unique1) - Workers Planned: 4 - -> Parallel Seq Scan on public.tenk1 - Output: unique1 - Filter: (tenk1.stringu1 = 'GRAAAA'::name) -(9 rows) - --- test parallel plan when group by expression is in target list. -explain (costs off) - select length(stringu1) from tenk1 group by length(stringu1); - QUERY PLAN ---------------------------------------------------- - Finalize HashAggregate - Group Key: (length((stringu1)::text)) - -> Gather - Workers Planned: 4 - -> Partial HashAggregate - Group Key: length((stringu1)::text) - -> Parallel Seq Scan on tenk1 -(7 rows) - -select length(stringu1) from tenk1 group by length(stringu1); - length --------- - 6 -(1 row) - -explain (costs off) - select stringu1, count(*) from tenk1 group by stringu1 order by stringu1; - QUERY PLAN ----------------------------------------------------- - Sort - Sort Key: stringu1 - -> Finalize HashAggregate - Group Key: stringu1 - -> Gather - Workers Planned: 4 - -> Partial HashAggregate - Group Key: stringu1 - -> Parallel Seq Scan on tenk1 -(9 rows) - --- test that parallel plan for aggregates is not selected when --- target list contains parallel restricted clause. -explain (costs off) - select sum(sp_parallel_restricted(unique1)) from tenk1 - group by(sp_parallel_restricted(unique1)); - QUERY PLAN -------------------------------------------------------------------- - HashAggregate - Group Key: sp_parallel_restricted(unique1) - -> Gather - Workers Planned: 4 - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 -(5 rows) - --- test prepared statement -prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1; -explain (costs off) execute tenk1_count(1); - QUERY PLAN ----------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Seq Scan on tenk1 - Filter: (hundred > 1) -(6 rows) - -execute tenk1_count(1); - count -------- - 9800 -(1 row) - -deallocate tenk1_count; --- test parallel plans for queries containing un-correlated subplans. -alter table tenk2 set (parallel_workers = 0); -explain (costs off) - select count(*) from tenk1 where (two, four) not in - (select hundred, thousand from tenk2 where thousand > 100); - QUERY PLAN ------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Seq Scan on tenk1 - Filter: (NOT (hashed SubPlan 1)) - SubPlan 1 - -> Seq Scan on tenk2 - Filter: (thousand > 100) -(9 rows) - -select count(*) from tenk1 where (two, four) not in - (select hundred, thousand from tenk2 where thousand > 100); - count -------- - 10000 -(1 row) - --- this is not parallel-safe due to use of random() within SubLink's testexpr: -explain (costs off) - select * from tenk1 where (unique1 + random())::integer not in - (select ten from tenk2); - QUERY PLAN ------------------------------------- - Seq Scan on tenk1 - Filter: (NOT (hashed SubPlan 1)) - SubPlan 1 - -> Seq Scan on tenk2 -(4 rows) - -alter table tenk2 reset (parallel_workers); --- test parallel plan for a query containing initplan. -set enable_indexscan = off; -set enable_indexonlyscan = off; -set enable_bitmapscan = off; -alter table tenk2 set (parallel_workers = 2); -explain (costs off) - select count(*) from tenk1 - where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2); - QUERY PLAN ------------------------------------------------------- - Aggregate - InitPlan 1 (returns $2) - -> Finalize Aggregate - -> Gather - Workers Planned: 2 - -> Partial Aggregate - -> Parallel Seq Scan on tenk2 - -> Gather - Workers Planned: 4 - Params Evaluated: $2 - -> Parallel Seq Scan on tenk1 - Filter: (unique1 = $2) -(12 rows) - -select count(*) from tenk1 - where tenk1.unique1 = (Select max(tenk2.unique1) from tenk2); - count -------- - 1 -(1 row) - -reset enable_indexscan; -reset enable_indexonlyscan; -reset enable_bitmapscan; -alter table tenk2 reset (parallel_workers); --- test parallel index scans. -set enable_seqscan to off; -set enable_bitmapscan to off; -explain (costs off) - select count((unique1)) from tenk1 where hundred > 1; - QUERY PLAN --------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Index Scan using tenk1_hundred on tenk1 - Index Cond: (hundred > 1) -(6 rows) - -select count((unique1)) from tenk1 where hundred > 1; - count -------- - 9800 -(1 row) - --- test parallel index-only scans. -explain (costs off) - select count(*) from tenk1 where thousand > 95; - QUERY PLAN --------------------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Index Only Scan using tenk1_thous_tenthous on tenk1 - Index Cond: (thousand > 95) -(6 rows) - -select count(*) from tenk1 where thousand > 95; - count -------- - 9040 -(1 row) - --- test rescan cases too -set enable_material = false; -explain (costs off) -select * from - (select count(unique1) from tenk1 where hundred > 10) ss - right join (values (1),(2),(3)) v(x) on true; - QUERY PLAN --------------------------------------------------------------------------- - Nested Loop Left Join - -> Values Scan on "*VALUES*" - -> Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Index Scan using tenk1_hundred on tenk1 - Index Cond: (hundred > 10) -(8 rows) - -select * from - (select count(unique1) from tenk1 where hundred > 10) ss - right join (values (1),(2),(3)) v(x) on true; - count | x --------+--- - 8900 | 1 - 8900 | 2 - 8900 | 3 -(3 rows) - -explain (costs off) -select * from - (select count(*) from tenk1 where thousand > 99) ss - right join (values (1),(2),(3)) v(x) on true; - QUERY PLAN --------------------------------------------------------------------------------------- - Nested Loop Left Join - -> Values Scan on "*VALUES*" - -> Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Index Only Scan using tenk1_thous_tenthous on tenk1 - Index Cond: (thousand > 99) -(8 rows) - -select * from - (select count(*) from tenk1 where thousand > 99) ss - right join (values (1),(2),(3)) v(x) on true; - count | x --------+--- - 9000 | 1 - 9000 | 2 - 9000 | 3 -(3 rows) - --- test rescans for a Limit node with a parallel node beneath it. -reset enable_seqscan; -set enable_indexonlyscan to off; -set enable_indexscan to off; -alter table tenk1 set (parallel_workers = 0); -alter table tenk2 set (parallel_workers = 1); -explain (costs off) -select count(*) from tenk1 - left join (select tenk2.unique1 from tenk2 order by 1 limit 1000) ss - on tenk1.unique1 < ss.unique1 + 1 - where tenk1.unique1 < 2; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Nested Loop Left Join - Join Filter: (tenk1.unique1 < (tenk2.unique1 + 1)) - -> Seq Scan on tenk1 - Filter: (unique1 < 2) - -> Limit - -> Gather Merge - Workers Planned: 1 - -> Sort - Sort Key: tenk2.unique1 - -> Parallel Seq Scan on tenk2 -(11 rows) - -select count(*) from tenk1 - left join (select tenk2.unique1 from tenk2 order by 1 limit 1000) ss - on tenk1.unique1 < ss.unique1 + 1 - where tenk1.unique1 < 2; - count -------- - 1999 -(1 row) - ---reset the value of workers for each table as it was before this test. -alter table tenk1 set (parallel_workers = 4); -alter table tenk2 reset (parallel_workers); -reset enable_material; -reset enable_bitmapscan; -reset enable_indexonlyscan; -reset enable_indexscan; --- test parallel bitmap heap scan. -set enable_seqscan to off; -set enable_indexscan to off; -set enable_hashjoin to off; -set enable_mergejoin to off; -set enable_material to off; --- test prefetching, if the platform allows it -DO $$ -BEGIN - SET effective_io_concurrency = 50; -EXCEPTION WHEN invalid_parameter_value THEN -END $$; -set work_mem='64kB'; --set small work mem to force lossy pages -explain (costs off) - select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; - QUERY PLAN ------------------------------------------------------------- - Aggregate - -> Nested Loop - -> Seq Scan on tenk2 - Filter: (thousand = 0) - -> Gather - Workers Planned: 4 - -> Parallel Bitmap Heap Scan on tenk1 - Recheck Cond: (hundred > 1) - -> Bitmap Index Scan on tenk1_hundred - Index Cond: (hundred > 1) -(10 rows) - -select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0; - count -------- - 98000 -(1 row) - -create table bmscantest (a int, t text); -insert into bmscantest select r, 'fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' FROM generate_series(1,100000) r; -create index i_bmtest ON bmscantest(a); -select count(*) from bmscantest where a>1; - count -------- - 99999 -(1 row) - --- test accumulation of stats for parallel nodes -reset enable_seqscan; -alter table tenk2 set (parallel_workers = 0); -explain (analyze, timing off, summary off, costs off) - select count(*) from tenk1, tenk2 where tenk1.hundred > 1 - and tenk2.thousand=0; - QUERY PLAN --------------------------------------------------------------------------- - Aggregate (actual rows=1 loops=1) - -> Nested Loop (actual rows=98000 loops=1) - -> Seq Scan on tenk2 (actual rows=10 loops=1) - Filter: (thousand = 0) - Rows Removed by Filter: 9990 - -> Gather (actual rows=9800 loops=10) - Workers Planned: 4 - Workers Launched: 4 - -> Parallel Seq Scan on tenk1 (actual rows=1960 loops=50) - Filter: (hundred > 1) - Rows Removed by Filter: 40 -(11 rows) - -alter table tenk2 reset (parallel_workers); -reset work_mem; -create function explain_parallel_sort_stats() returns setof text -language plpgsql as -$$ -declare ln text; -begin - for ln in - explain (analyze, timing off, summary off, costs off) - select * from - (select ten from tenk1 where ten < 100 order by ten) ss - right join (values (1),(2),(3)) v(x) on true - loop - ln := regexp_replace(ln, 'Memory: \S*', 'Memory: xxx'); - return next ln; - end loop; -end; -$$; -select * from explain_parallel_sort_stats(); - explain_parallel_sort_stats --------------------------------------------------------------------------- - Nested Loop Left Join (actual rows=30000 loops=1) - -> Values Scan on "*VALUES*" (actual rows=3 loops=1) - -> Gather Merge (actual rows=10000 loops=3) - Workers Planned: 4 - Workers Launched: 4 - -> Sort (actual rows=2000 loops=15) - Sort Key: tenk1.ten - Sort Method: quicksort Memory: xxx - Worker 0: Sort Method: quicksort Memory: xxx - Worker 1: Sort Method: quicksort Memory: xxx - Worker 2: Sort Method: quicksort Memory: xxx - Worker 3: Sort Method: quicksort Memory: xxx - -> Parallel Seq Scan on tenk1 (actual rows=2000 loops=15) - Filter: (ten < 100) -(14 rows) - -reset enable_indexscan; -reset enable_hashjoin; -reset enable_mergejoin; -reset enable_material; -reset effective_io_concurrency; -drop table bmscantest; -drop function explain_parallel_sort_stats(); --- test parallel merge join path. -set enable_hashjoin to off; -set enable_nestloop to off; -explain (costs off) - select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1; - QUERY PLAN -------------------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Merge Join - Merge Cond: (tenk1.unique1 = tenk2.unique1) - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 - -> Index Only Scan using tenk2_unique1 on tenk2 -(8 rows) - -select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1; - count -------- - 10000 -(1 row) - -reset enable_hashjoin; -reset enable_nestloop; --- test gather merge -set enable_hashagg = false; -explain (costs off) - select count(*) from tenk1 group by twenty; - QUERY PLAN ----------------------------------------------------- - Finalize GroupAggregate - Group Key: twenty - -> Gather Merge - Workers Planned: 4 - -> Partial GroupAggregate - Group Key: twenty - -> Sort - Sort Key: twenty - -> Parallel Seq Scan on tenk1 -(9 rows) - -select count(*) from tenk1 group by twenty; - count -------- - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 -(20 rows) - ---test expressions in targetlist are pushed down for gather merge -create function sp_simple_func(var1 integer) returns integer -as $$ -begin - return var1 + 10; -end; -$$ language plpgsql PARALLEL SAFE; -explain (costs off, verbose) - select ten, sp_simple_func(ten) from tenk1 where ten < 100 order by ten; - QUERY PLAN ------------------------------------------------------ - Gather Merge - Output: ten, (sp_simple_func(ten)) - Workers Planned: 4 - -> Result - Output: ten, sp_simple_func(ten) - -> Sort - Output: ten - Sort Key: tenk1.ten - -> Parallel Seq Scan on public.tenk1 - Output: ten - Filter: (tenk1.ten < 100) -(11 rows) - -drop function sp_simple_func(integer); --- test handling of SRFs in targetlist (bug in 10.0) -explain (costs off) - select count(*), generate_series(1,2) from tenk1 group by twenty; - QUERY PLAN ----------------------------------------------------------- - ProjectSet - -> Finalize GroupAggregate - Group Key: twenty - -> Gather Merge - Workers Planned: 4 - -> Partial GroupAggregate - Group Key: twenty - -> Sort - Sort Key: twenty - -> Parallel Seq Scan on tenk1 -(10 rows) - -select count(*), generate_series(1,2) from tenk1 group by twenty; - count | generate_series --------+----------------- - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 - 500 | 1 - 500 | 2 -(40 rows) - --- test gather merge with parallel leader participation disabled -set parallel_leader_participation = off; -explain (costs off) - select count(*) from tenk1 group by twenty; - QUERY PLAN ----------------------------------------------------- - Finalize GroupAggregate - Group Key: twenty - -> Gather Merge - Workers Planned: 4 - -> Partial GroupAggregate - Group Key: twenty - -> Sort - Sort Key: twenty - -> Parallel Seq Scan on tenk1 -(9 rows) - -select count(*) from tenk1 group by twenty; - count -------- - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 - 500 -(20 rows) - -reset parallel_leader_participation; ---test rescan behavior of gather merge -set enable_material = false; -explain (costs off) -select * from - (select string4, count(unique2) - from tenk1 group by string4 order by string4) ss - right join (values (1),(2),(3)) v(x) on true; - QUERY PLAN ----------------------------------------------------------- - Nested Loop Left Join - -> Values Scan on "*VALUES*" - -> Finalize GroupAggregate - Group Key: tenk1.string4 - -> Gather Merge - Workers Planned: 4 - -> Partial GroupAggregate - Group Key: tenk1.string4 - -> Sort - Sort Key: tenk1.string4 - -> Parallel Seq Scan on tenk1 -(11 rows) - -select * from - (select string4, count(unique2) - from tenk1 group by string4 order by string4) ss - right join (values (1),(2),(3)) v(x) on true; - string4 | count | x ----------+-------+--- - AAAAxx | 2500 | 1 - HHHHxx | 2500 | 1 - OOOOxx | 2500 | 1 - VVVVxx | 2500 | 1 - AAAAxx | 2500 | 2 - HHHHxx | 2500 | 2 - OOOOxx | 2500 | 2 - VVVVxx | 2500 | 2 - AAAAxx | 2500 | 3 - HHHHxx | 2500 | 3 - OOOOxx | 2500 | 3 - VVVVxx | 2500 | 3 -(12 rows) - -reset enable_material; -reset enable_hashagg; --- check parallelized int8 aggregate (bug #14897) -explain (costs off) -select avg(unique1::int8) from tenk1; - QUERY PLAN -------------------------------------------------------------------------- - Finalize Aggregate - -> Gather - Workers Planned: 4 - -> Partial Aggregate - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 -(5 rows) - -select avg(unique1::int8) from tenk1; - avg ------------------------ - 4999.5000000000000000 -(1 row) - --- gather merge test with a LIMIT -explain (costs off) - select fivethous from tenk1 order by fivethous limit 4; - QUERY PLAN ----------------------------------------------- - Limit - -> Gather Merge - Workers Planned: 4 - -> Sort - Sort Key: fivethous - -> Parallel Seq Scan on tenk1 -(6 rows) - -select fivethous from tenk1 order by fivethous limit 4; - fivethous ------------ - 0 - 0 - 1 - 1 -(4 rows) - --- gather merge test with 0 worker -set max_parallel_workers = 0; -explain (costs off) - select string4 from tenk1 order by string4 limit 5; - QUERY PLAN ----------------------------------------------- - Limit - -> Gather Merge - Workers Planned: 4 - -> Sort - Sort Key: string4 - -> Parallel Seq Scan on tenk1 -(6 rows) - -select string4 from tenk1 order by string4 limit 5; - string4 ---------- - AAAAxx - AAAAxx - AAAAxx - AAAAxx - AAAAxx -(5 rows) - --- gather merge test with 0 workers, with parallel leader --- participation disabled (the leader will have to run the plan --- despite the setting) -set parallel_leader_participation = off; -explain (costs off) - select string4 from tenk1 order by string4 limit 5; - QUERY PLAN ----------------------------------------------- - Limit - -> Gather Merge - Workers Planned: 4 - -> Sort - Sort Key: string4 - -> Parallel Seq Scan on tenk1 -(6 rows) - -select string4 from tenk1 order by string4 limit 5; - string4 ---------- - AAAAxx - AAAAxx - AAAAxx - AAAAxx - AAAAxx -(5 rows) - -reset parallel_leader_participation; -reset max_parallel_workers; -SAVEPOINT settings; -SET LOCAL force_parallel_mode = 1; -explain (costs off) - select stringu1::int2 from tenk1 where unique1 = 1; - QUERY PLAN ------------------------------------------------ - Gather - Workers Planned: 1 - Single Copy: true - -> Index Scan using tenk1_unique1 on tenk1 - Index Cond: (unique1 = 1) -(5 rows) - -ROLLBACK TO SAVEPOINT settings; --- exercise record typmod remapping between backends -CREATE FUNCTION make_record(n int) - RETURNS RECORD LANGUAGE plpgsql PARALLEL SAFE AS -$$ -BEGIN - RETURN CASE n - WHEN 1 THEN ROW(1) - WHEN 2 THEN ROW(1, 2) - WHEN 3 THEN ROW(1, 2, 3) - WHEN 4 THEN ROW(1, 2, 3, 4) - ELSE ROW(1, 2, 3, 4, 5) - END; -END; -$$; -SAVEPOINT settings; -SET LOCAL force_parallel_mode = 1; -SELECT make_record(x) FROM (SELECT generate_series(1, 5) x) ss ORDER BY x; - make_record -------------- - (1) - (1,2) - (1,2,3) - (1,2,3,4) - (1,2,3,4,5) -(5 rows) - -ROLLBACK TO SAVEPOINT settings; -DROP function make_record(n int); --- test the sanity of parallel query after the active role is dropped. -drop role if exists regress_parallel_worker; -NOTICE: role "regress_parallel_worker" does not exist, skipping -create role regress_parallel_worker; -set role regress_parallel_worker; -reset session authorization; -drop role regress_parallel_worker; -set force_parallel_mode = 1; -select count(*) from tenk1; - count -------- - 10000 -(1 row) - -reset force_parallel_mode; -reset role; --- Window function calculation can't be pushed to workers. -explain (costs off, verbose) - select count(*) from tenk1 a where (unique1, two) in - (select unique1, row_number() over() from tenk1 b); - QUERY PLAN ----------------------------------------------------------------------------------------------- - Aggregate - Output: count(*) - -> Hash Semi Join - Hash Cond: ((a.unique1 = b.unique1) AND (a.two = (row_number() OVER (?)))) - -> Gather - Output: a.unique1, a.two - Workers Planned: 4 - -> Parallel Seq Scan on public.tenk1 a - Output: a.unique1, a.two - -> Hash - Output: b.unique1, (row_number() OVER (?)) - -> WindowAgg - Output: b.unique1, row_number() OVER (?) - -> Gather - Output: b.unique1 - Workers Planned: 4 - -> Parallel Index Only Scan using tenk1_unique1 on public.tenk1 b - Output: b.unique1 -(18 rows) - --- LIMIT/OFFSET within sub-selects can't be pushed to workers. -explain (costs off) - select * from tenk1 a where two in - (select two from tenk1 b where stringu1 like '%AAAA' limit 3); - QUERY PLAN ---------------------------------------------------------------- - Hash Semi Join - Hash Cond: (a.two = b.two) - -> Gather - Workers Planned: 4 - -> Parallel Seq Scan on tenk1 a - -> Hash - -> Limit - -> Gather - Workers Planned: 4 - -> Parallel Seq Scan on tenk1 b - Filter: (stringu1 ~~ '%AAAA'::text) -(11 rows) - --- to increase the parallel query test coverage -SAVEPOINT settings; -SET LOCAL force_parallel_mode = 1; -EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1; - QUERY PLAN -------------------------------------------------------------- - Gather (actual rows=10000 loops=1) - Workers Planned: 4 - Workers Launched: 4 - -> Parallel Seq Scan on tenk1 (actual rows=2000 loops=5) -(4 rows) - -ROLLBACK TO SAVEPOINT settings; --- provoke error in worker --- (make the error message long enough to require multiple bufferloads) -SAVEPOINT settings; -SET LOCAL force_parallel_mode = 1; -select (stringu1 || repeat('abcd', 5000))::int2 from tenk1 where unique1 = 1; -ERROR: invalid input syntax for type smallint: "BAAAAAabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd" -CONTEXT: parallel worker -ROLLBACK TO SAVEPOINT settings; --- test interaction with set-returning functions -SAVEPOINT settings; --- multiple subqueries under a single Gather node --- must set parallel_setup_cost > 0 to discourage multiple Gather nodes -SET LOCAL parallel_setup_cost = 10; -EXPLAIN (COSTS OFF) -SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1 -UNION ALL -SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1; - QUERY PLAN ----------------------------------------------------- - Gather - Workers Planned: 4 - -> Parallel Append - -> Parallel Seq Scan on tenk1 - Filter: (fivethous = (tenthous + 1)) - -> Parallel Seq Scan on tenk1 tenk1_1 - Filter: (fivethous = (tenthous + 1)) -(7 rows) - -ROLLBACK TO SAVEPOINT settings; --- can't use multiple subqueries under a single Gather node due to initPlans -EXPLAIN (COSTS OFF) -SELECT unique1 FROM tenk1 WHERE fivethous = - (SELECT unique1 FROM tenk1 WHERE fivethous = 1 LIMIT 1) -UNION ALL -SELECT unique1 FROM tenk1 WHERE fivethous = - (SELECT unique2 FROM tenk1 WHERE fivethous = 1 LIMIT 1) -ORDER BY 1; - QUERY PLAN --------------------------------------------------------------------- - Sort - Sort Key: tenk1.unique1 - -> Append - -> Gather - Workers Planned: 4 - Params Evaluated: $1 - InitPlan 1 (returns $1) - -> Limit - -> Gather - Workers Planned: 4 - -> Parallel Seq Scan on tenk1 tenk1_2 - Filter: (fivethous = 1) - -> Parallel Seq Scan on tenk1 - Filter: (fivethous = $1) - -> Gather - Workers Planned: 4 - Params Evaluated: $3 - InitPlan 2 (returns $3) - -> Limit - -> Gather - Workers Planned: 4 - -> Parallel Seq Scan on tenk1 tenk1_3 - Filter: (fivethous = 1) - -> Parallel Seq Scan on tenk1 tenk1_1 - Filter: (fivethous = $3) -(25 rows) - --- test interaction with SRFs -SELECT * FROM information_schema.foreign_data_wrapper_options -ORDER BY 1, 2, 3; - foreign_data_wrapper_catalog | foreign_data_wrapper_name | option_name | option_value -------------------------------+---------------------------+-------------+-------------- -(0 rows) - -EXPLAIN (VERBOSE, COSTS OFF) -SELECT generate_series(1, two), array(select generate_series(1, two)) - FROM tenk1 ORDER BY tenthous; - QUERY PLAN ----------------------------------------------------------------------- - ProjectSet - Output: generate_series(1, tenk1.two), (SubPlan 1), tenk1.tenthous - -> Gather Merge - Output: tenk1.two, tenk1.tenthous - Workers Planned: 4 - -> Result - Output: tenk1.two, tenk1.tenthous - -> Sort - Output: tenk1.tenthous, tenk1.two - Sort Key: tenk1.tenthous - -> Parallel Seq Scan on public.tenk1 - Output: tenk1.tenthous, tenk1.two - SubPlan 1 - -> ProjectSet - Output: generate_series(1, tenk1.two) - -> Result -(16 rows) - --- test passing expanded-value representations to workers -CREATE FUNCTION make_some_array(int,int) returns int[] as -$$declare x int[]; - begin - x[1] := $1; - x[2] := $2; - return x; - end$$ language plpgsql parallel safe; -CREATE TABLE fooarr(f1 text, f2 int[], f3 text); -INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one'); -PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2; -EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2)); - QUERY PLAN ------------------------------------------------------------------- - Gather - Workers Planned: 3 - -> Parallel Seq Scan on fooarr - Filter: ((f1 = '1'::text) AND (f2 = '{1,2}'::integer[])) -(4 rows) - -EXECUTE pstmt('1', make_some_array(1,2)); - f1 | f2 | f3 -----+-------+----- - 1 | {1,2} | one -(1 row) - -DEALLOCATE pstmt; --- test interaction between subquery and partial_paths -CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1; -EXPLAIN (COSTS OFF) -SELECT 1 FROM tenk1_vw_sec - WHERE (SELECT sum(f1) FROM int4_tbl WHERE f1 < unique1) < 100; - QUERY PLAN -------------------------------------------------------------------- - Subquery Scan on tenk1_vw_sec - Filter: ((SubPlan 1) < 100) - -> Gather - Workers Planned: 4 - -> Parallel Index Only Scan using tenk1_unique1 on tenk1 - SubPlan 1 - -> Aggregate - -> Seq Scan on int4_tbl - Filter: (f1 < tenk1_vw_sec.unique1) -(9 rows) - -rollback; +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/tsearch.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/tsearch.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/tsearch.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/tsearch.out 2022-02-13 01:13:19.565611116 +0100 @@ -255,2593 +255,8 @@ (1 row) SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; - count -------- - 3 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; - count -------- - 432 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; - count -------- - 56 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; - count -------- - 58 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; - count -------- - 452 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; - count -------- - 450 -(1 row) - -SET enable_indexscan=OFF; -SET enable_bitmapscan=ON; -explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - QUERY PLAN -------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: (a @@ '''wr'' | ''qh'''::tsquery) - -> Bitmap Index Scan on wowidx - Index Cond: (a @@ '''wr'' | ''qh'''::tsquery) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; - count -------- - 17 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; - count -------- - 98 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 23 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 39 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; - count -------- - 494 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; - count -------- - 3 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; - count -------- - 432 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; - count -------- - 56 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; - count -------- - 58 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; - count -------- - 452 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; - count -------- - 450 -(1 row) - --- Test siglen parameter of GiST tsvector_ops -CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(foo=1)); -ERROR: unrecognized parameter "foo" -CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=0)); -ERROR: value 0 out of bounds for option "siglen" -DETAIL: Valid values are between "1" and "2024". -CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=2048)); -ERROR: value 2048 out of bounds for option "siglen" -DETAIL: Valid values are between "1" and "2024". -CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100,foo='bar')); -ERROR: unrecognized parameter "foo" -CREATE INDEX wowidx1 ON test_tsvector USING gist (a tsvector_ops(siglen=100, siglen = 200)); -ERROR: parameter "siglen" specified more than once -CREATE INDEX wowidx2 ON test_tsvector USING gist (a tsvector_ops(siglen=1)); -\d test_tsvector - Table "public.test_tsvector" - Column | Type | Collation | Nullable | Default ---------+----------+-----------+----------+--------- - t | text | | | - a | tsvector | | | -Indexes: - "wowidx" gist (a) - "wowidx2" gist (a tsvector_ops (siglen='1')) - -DROP INDEX wowidx; -EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - QUERY PLAN -------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: (a @@ '''wr'' | ''qh'''::tsquery) - -> Bitmap Index Scan on wowidx2 - Index Cond: (a @@ '''wr'' | ''qh'''::tsquery) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; - count -------- - 17 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; - count -------- - 98 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 23 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 39 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; - count -------- - 494 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; - count -------- - 3 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; - count -------- - 432 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; - count -------- - 56 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; - count -------- - 58 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; - count -------- - 452 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; - count -------- - 450 -(1 row) - -DROP INDEX wowidx2; -CREATE INDEX wowidx ON test_tsvector USING gist (a tsvector_ops(siglen=484)); -\d test_tsvector - Table "public.test_tsvector" - Column | Type | Collation | Nullable | Default ---------+----------+-----------+----------+--------- - t | text | | | - a | tsvector | | | -Indexes: - "wowidx" gist (a tsvector_ops (siglen='484')) - -EXPLAIN (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - QUERY PLAN -------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: (a @@ '''wr'' | ''qh'''::tsquery) - -> Bitmap Index Scan on wowidx - Index Cond: (a @@ '''wr'' | ''qh'''::tsquery) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; - count -------- - 17 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; - count -------- - 98 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 23 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 39 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; - count -------- - 494 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; - count -------- - 3 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; - count -------- - 432 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; - count -------- - 56 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; - count -------- - 58 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; - count -------- - 452 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; - count -------- - 450 -(1 row) - -RESET enable_seqscan; -RESET enable_indexscan; -RESET enable_bitmapscan; -DROP INDEX wowidx; -CREATE INDEX wowidx ON test_tsvector USING gin (a); -SET enable_seqscan=OFF; --- GIN only supports bitmapscan, so no need to test plain indexscan -explain (costs off) SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - QUERY PLAN -------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: (a @@ '''wr'' | ''qh'''::tsquery) - -> Bitmap Index Scan on wowidx - Index Cond: (a @@ '''wr'' | ''qh'''::tsquery) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr|qh'; - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr&qh'; - count -------- - 17 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq&yt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'eq|yt'; - count -------- - 98 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 23 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 39 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'w:*|q:*'; - count -------- - 494 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ any ('{wr,qh}'); - count -------- - 158 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'no_such_lexeme'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!no_such_lexeme'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'pl <-> yh'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'yh <-> pl'; - count -------- - 0 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'qe <2> qt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> yh'; - count -------- - 3 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!pl <-> !yh'; - count -------- - 432 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!yh <-> pl'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qe <2> qt'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(pl <-> yh)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(yh <-> pl)'; - count -------- - 508 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!(qe <2> qt)'; - count -------- - 507 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:A'; - count -------- - 56 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wd:D'; - count -------- - 58 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:A'; - count -------- - 452 -(1 row) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!wd:D'; - count -------- - 450 -(1 row) - --- Test optimization of non-empty GIN_SEARCH_MODE_ALL queries -EXPLAIN (COSTS OFF) -SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'; - QUERY PLAN ------------------------------------------------------ - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: (a @@ '!''qh'''::tsquery) - -> Bitmap Index Scan on wowidx - Index Cond: (a @@ '!''qh'''::tsquery) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ '!qh'; - count -------- - 410 -(1 row) - -EXPLAIN (COSTS OFF) -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'; - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - -> Bitmap Heap Scan on test_tsvector - Recheck Cond: ((a @@ '''wr'''::tsquery) AND (a @@ '!''qh'''::tsquery)) - -> Bitmap Index Scan on wowidx - Index Cond: ((a @@ '''wr'''::tsquery) AND (a @@ '!''qh'''::tsquery)) -(5 rows) - -SELECT count(*) FROM test_tsvector WHERE a @@ 'wr' AND a @@ '!qh'; - count -------- - 60 -(1 row) - -RESET enable_seqscan; -INSERT INTO test_tsvector VALUES ('???', 'DFG:1A,2B,6C,10 FGH'); -SELECT * FROM ts_stat('SELECT a FROM test_tsvector') ORDER BY ndoc DESC, nentry DESC, word LIMIT 10; - word | ndoc | nentry -------+------+-------- - qq | 108 | 108 - qt | 102 | 102 - qe | 100 | 101 - qh | 98 | 99 - qw | 98 | 98 - qa | 97 | 97 - ql | 94 | 94 - qs | 94 | 94 - qr | 92 | 93 - qi | 92 | 92 -(10 rows) - -SELECT * FROM ts_stat('SELECT a FROM test_tsvector', 'AB') ORDER BY ndoc DESC, nentry DESC, word; - word | ndoc | nentry -------+------+-------- - DFG | 1 | 2 -(1 row) - ---dictionaries and to_tsvector -SELECT ts_lexize('english_stem', 'skies'); - ts_lexize ------------ - {sky} -(1 row) - -SELECT ts_lexize('english_stem', 'identity'); - ts_lexize ------------ - {ident} -(1 row) - -SELECT * FROM ts_token_type('default'); - tokid | alias | description --------+-----------------+------------------------------------------ - 1 | asciiword | Word, all ASCII - 2 | word | Word, all letters - 3 | numword | Word, letters and digits - 4 | email | Email address - 5 | url | URL - 6 | host | Host - 7 | sfloat | Scientific notation - 8 | version | Version number - 9 | hword_numpart | Hyphenated word part, letters and digits - 10 | hword_part | Hyphenated word part, all letters - 11 | hword_asciipart | Hyphenated word part, all ASCII - 12 | blank | Space symbols - 13 | tag | XML tag - 14 | protocol | Protocol head - 15 | numhword | Hyphenated word, letters and digits - 16 | asciihword | Hyphenated word, all ASCII - 17 | hword | Hyphenated word, all letters - 18 | url_path | URL path - 19 | file | File or path name - 20 | float | Decimal notation - 21 | int | Signed integer - 22 | uint | Unsigned integer - 23 | entity | XML entity -(23 rows) - -SELECT * FROM ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty'); - tokid | token --------+-------------------------------------- - 22 | 345 - 12 | - 1 | qwe - 12 | @ - 19 | efd.r - 12 | ' - 14 | http:// - 6 | www.com - 12 | / - 14 | http:// - 5 | aew.werc.ewr/?ad=qwe&dw - 6 | aew.werc.ewr - 18 | /?ad=qwe&dw - 12 | - 5 | 1aew.werc.ewr/?ad=qwe&dw - 6 | 1aew.werc.ewr - 18 | /?ad=qwe&dw - 12 | - 6 | 2aew.werc.ewr - 12 | - 14 | http:// - 5 | 3aew.werc.ewr/?ad=qwe&dw - 6 | 3aew.werc.ewr - 18 | /?ad=qwe&dw - 12 | - 14 | http:// - 6 | 4aew.werc.ewr - 12 | - 14 | http:// - 5 | 5aew.werc.ewr:8100/? - 6 | 5aew.werc.ewr:8100 - 18 | /? - 12 | - 1 | ad - 12 | = - 1 | qwe - 12 | & - 1 | dw - 12 | - 5 | 6aew.werc.ewr:8100/?ad=qwe&dw - 6 | 6aew.werc.ewr:8100 - 18 | /?ad=qwe&dw - 12 | - 5 | 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 - 6 | 7aew.werc.ewr:8100 - 18 | /?ad=qwe&dw=%20%32 - 12 | - 7 | +4.0e-10 - 12 | - 1 | qwe - 12 | - 1 | qwe - 12 | - 1 | qwqwe - 12 | - 20 | 234.435 - 12 | - 22 | 455 - 12 | - 20 | 5.005 - 12 | - 4 | teodor@stack.net - 12 | - 4 | teodor@123-stack.net - 12 | - 4 | 123_teodor@stack.net - 12 | - 4 | 123-teodor@stack.net - 12 | - 16 | qwe-wer - 11 | qwe - 12 | - - 11 | wer - 12 | - 1 | asdf - 12 | - 13 | - 1 | qwer - 12 | - 1 | jf - 12 | - 1 | sdjk - 12 | < - 1 | we - 12 | - 1 | hjwer - 12 | - 13 | - 12 | - 3 | ewr1 - 12 | > - 3 | ewri2 - 12 | - 13 | - 12 | + - | - 19 | /usr/local/fff - 12 | - 19 | /awdf/dwqe/4325 - 12 | - 19 | rewt/ewr - 12 | - 1 | wefjn - 12 | - 19 | /wqe-324/ewr - 12 | - 19 | gist.h - 12 | - 19 | gist.h.c - 12 | - 19 | gist.c - 12 | . - 1 | readline - 12 | - 20 | 4.2 - 12 | - 20 | 4.2 - 12 | . - 20 | 4.2 - 12 | , - 1 | readline - 20 | -4.2 - 12 | - 1 | readline - 20 | -4.2 - 12 | . - 22 | 234 - 12 | + - | - 12 | < - 1 | i - 12 | - 13 | - 12 | - 1 | wow - 12 | - 12 | < - 1 | jqw - 12 | - 12 | <> - 1 | qwerty -(139 rows) - -SELECT to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty'); - to_tsvector ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - '+4.0e-10':28 '-4.2':63,65 '/?':18 '/?ad=qwe&dw':7,10,14,24 '/?ad=qwe&dw=%20%32':27 '/awdf/dwqe/4325':51 '/usr/local/fff':50 '/wqe-324/ewr':54 '123-teodor@stack.net':38 '123_teodor@stack.net':37 '1aew.werc.ewr':9 '1aew.werc.ewr/?ad=qwe&dw':8 '234':66 '234.435':32 '2aew.werc.ewr':11 '345':1 '3aew.werc.ewr':13 '3aew.werc.ewr/?ad=qwe&dw':12 '4.2':59,60,61 '455':33 '4aew.werc.ewr':15 '5.005':34 '5aew.werc.ewr:8100':17 '5aew.werc.ewr:8100/?':16 '6aew.werc.ewr:8100':23 '6aew.werc.ewr:8100/?ad=qwe&dw':22 '7aew.werc.ewr:8100':26 '7aew.werc.ewr:8100/?ad=qwe&dw=%20%32':25 'ad':19 'aew.werc.ewr':6 'aew.werc.ewr/?ad=qwe&dw':5 'asdf':42 'dw':21 'efd.r':3 'ewr1':48 'ewri2':49 'gist.c':57 'gist.h':55 'gist.h.c':56 'hjwer':47 'jf':44 'jqw':69 'qwe':2,20,29,30,40 'qwe-wer':39 'qwer':43 'qwerti':70 'qwqwe':31 'readlin':58,62,64 'rewt/ewr':52 'sdjk':45 'teodor@123-stack.net':36 'teodor@stack.net':35 'wefjn':53 'wer':41 'wow':68 'www.com':4 -(1 row) - -SELECT length(to_tsvector('english', '345 qwe@efd.r '' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net teodor@123-stack.net 123_teodor@stack.net 123-teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty')); - length --------- - 56 -(1 row) - --- ts_debug -SELECT * from ts_debug('english', 'abc&nm1;def©ghiõjkl'); - alias | description | token | dictionaries | dictionary | lexemes ------------+-----------------+----------------------------+----------------+--------------+--------- - tag | XML tag | | {} | | - asciiword | Word, all ASCII | abc | {english_stem} | english_stem | {abc} - entity | XML entity | &nm1; | {} | | - asciiword | Word, all ASCII | def | {english_stem} | english_stem | {def} - entity | XML entity | © | {} | | - asciiword | Word, all ASCII | ghi | {english_stem} | english_stem | {ghi} - entity | XML entity | õ | {} | | - asciiword | Word, all ASCII | jkl | {english_stem} | english_stem | {jkl} - tag | XML tag | | {} | | -(9 rows) - --- check parsing of URLs -SELECT * from ts_debug('english', 'http://www.harewoodsolutions.co.uk/press.aspx'); - alias | description | token | dictionaries | dictionary | lexemes -----------+---------------+----------------------------------------+--------------+------------+------------------------------------------ - protocol | Protocol head | http:// | {} | | - url | URL | www.harewoodsolutions.co.uk/press.aspx | {simple} | simple | {www.harewoodsolutions.co.uk/press.aspx} - host | Host | www.harewoodsolutions.co.uk | {simple} | simple | {www.harewoodsolutions.co.uk} - url_path | URL path | /press.aspx | {simple} | simple | {/press.aspx} - tag | XML tag | | {} | | -(5 rows) - -SELECT * from ts_debug('english', 'http://aew.wer0c.ewr/id?ad=qwe&dw'); - alias | description | token | dictionaries | dictionary | lexemes -----------+---------------+----------------------------+--------------+------------+------------------------------ - protocol | Protocol head | http:// | {} | | - url | URL | aew.wer0c.ewr/id?ad=qwe&dw | {simple} | simple | {aew.wer0c.ewr/id?ad=qwe&dw} - host | Host | aew.wer0c.ewr | {simple} | simple | {aew.wer0c.ewr} - url_path | URL path | /id?ad=qwe&dw | {simple} | simple | {/id?ad=qwe&dw} - tag | XML tag | | {} | | -(5 rows) - -SELECT * from ts_debug('english', 'http://5aew.werc.ewr:8100/?'); - alias | description | token | dictionaries | dictionary | lexemes -----------+---------------+----------------------+--------------+------------+------------------------ - protocol | Protocol head | http:// | {} | | - url | URL | 5aew.werc.ewr:8100/? | {simple} | simple | {5aew.werc.ewr:8100/?} - host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100} - url_path | URL path | /? | {simple} | simple | {/?} -(4 rows) - -SELECT * from ts_debug('english', '5aew.werc.ewr:8100/?xx'); - alias | description | token | dictionaries | dictionary | lexemes -----------+-------------+------------------------+--------------+------------+-------------------------- - url | URL | 5aew.werc.ewr:8100/?xx | {simple} | simple | {5aew.werc.ewr:8100/?xx} - host | Host | 5aew.werc.ewr:8100 | {simple} | simple | {5aew.werc.ewr:8100} - url_path | URL path | /?xx | {simple} | simple | {/?xx} -(3 rows) - -SELECT token, alias, - dictionaries, dictionaries is null as dnull, array_dims(dictionaries) as ddims, - lexemes, lexemes is null as lnull, array_dims(lexemes) as ldims -from ts_debug('english', 'a title'); - token | alias | dictionaries | dnull | ddims | lexemes | lnull | ldims --------+-----------+----------------+-------+-------+---------+-------+------- - a | asciiword | {english_stem} | f | [1:1] | {} | f | - | blank | {} | f | | | t | - title | asciiword | {english_stem} | f | [1:1] | {titl} | f | [1:1] -(3 rows) - --- to_tsquery -SELECT to_tsquery('english', 'qwe & sKies '); - to_tsquery ---------------- - 'qwe' & 'sky' -(1 row) - -SELECT to_tsquery('simple', 'qwe & sKies '); - to_tsquery ------------------ - 'qwe' & 'skies' -(1 row) - -SELECT to_tsquery('english', '''the wether'':dc & '' sKies '':BC '); - to_tsquery ------------------------- - 'wether':CD & 'sky':BC -(1 row) - -SELECT to_tsquery('english', 'asd&(and|fghj)'); - to_tsquery ----------------- - 'asd' & 'fghj' -(1 row) - -SELECT to_tsquery('english', '(asd&and)|fghj'); - to_tsquery ----------------- - 'asd' | 'fghj' -(1 row) - -SELECT to_tsquery('english', '(asd&!and)|fghj'); - to_tsquery ----------------- - 'asd' | 'fghj' -(1 row) - -SELECT to_tsquery('english', '(the|and&(i&1))&fghj'); - to_tsquery --------------- - '1' & 'fghj' -(1 row) - -SELECT plainto_tsquery('english', 'the and z 1))& fghj'); - plainto_tsquery --------------------- - 'z' & '1' & 'fghj' -(1 row) - -SELECT plainto_tsquery('english', 'foo bar') && plainto_tsquery('english', 'asd'); - ?column? ------------------------ - 'foo' & 'bar' & 'asd' -(1 row) - -SELECT plainto_tsquery('english', 'foo bar') || plainto_tsquery('english', 'asd fg'); - ?column? ------------------------------- - 'foo' & 'bar' | 'asd' & 'fg' -(1 row) - -SELECT plainto_tsquery('english', 'foo bar') || !!plainto_tsquery('english', 'asd fg'); - ?column? ------------------------------------ - 'foo' & 'bar' | !( 'asd' & 'fg' ) -(1 row) - -SELECT plainto_tsquery('english', 'foo bar') && 'asd | fg'; - ?column? ----------------------------------- - 'foo' & 'bar' & ( 'asd' | 'fg' ) -(1 row) - --- Check stop word deletion, a and s are stop-words -SELECT to_tsquery('english', '!(a & !b) & c'); - to_tsquery -------------- - !!'b' & 'c' -(1 row) - -SELECT to_tsquery('english', '!(a & !b)'); - to_tsquery ------------- - !!'b' -(1 row) - -SELECT to_tsquery('english', '(1 <-> 2) <-> a'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '(1 <-> a) <-> 2'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', '(a <-> 1) <-> 2'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', 'a <-> (1 <-> 2)'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '1 <-> (a <-> 2)'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', '1 <-> (2 <-> a)'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '(1 <-> 2) <3> a'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '(1 <-> a) <3> 2'); - to_tsquery -------------- - '1' <4> '2' -(1 row) - -SELECT to_tsquery('english', '(a <-> 1) <3> 2'); - to_tsquery -------------- - '1' <3> '2' -(1 row) - -SELECT to_tsquery('english', 'a <3> (1 <-> 2)'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '1 <3> (a <-> 2)'); - to_tsquery -------------- - '1' <4> '2' -(1 row) - -SELECT to_tsquery('english', '1 <3> (2 <-> a)'); - to_tsquery -------------- - '1' <3> '2' -(1 row) - -SELECT to_tsquery('english', '(1 <3> 2) <-> a'); - to_tsquery -------------- - '1' <3> '2' -(1 row) - -SELECT to_tsquery('english', '(1 <3> a) <-> 2'); - to_tsquery -------------- - '1' <4> '2' -(1 row) - -SELECT to_tsquery('english', '(a <3> 1) <-> 2'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', 'a <-> (1 <3> 2)'); - to_tsquery -------------- - '1' <3> '2' -(1 row) - -SELECT to_tsquery('english', '1 <-> (a <3> 2)'); - to_tsquery -------------- - '1' <4> '2' -(1 row) - -SELECT to_tsquery('english', '1 <-> (2 <3> a)'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '((a <-> 1) <-> 2) <-> s'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '(2 <-> (a <-> 1)) <-> s'); - to_tsquery -------------- - '2' <2> '1' -(1 row) - -SELECT to_tsquery('english', '((1 <-> a) <-> 2) <-> s'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', '(2 <-> (1 <-> a)) <-> s'); - to_tsquery -------------- - '2' <-> '1' -(1 row) - -SELECT to_tsquery('english', 's <-> ((a <-> 1) <-> 2)'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', 's <-> (2 <-> (a <-> 1))'); - to_tsquery -------------- - '2' <2> '1' -(1 row) - -SELECT to_tsquery('english', 's <-> ((1 <-> a) <-> 2)'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', 's <-> (2 <-> (1 <-> a))'); - to_tsquery -------------- - '2' <-> '1' -(1 row) - -SELECT to_tsquery('english', '((a <-> 1) <-> s) <-> 2'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', '(s <-> (a <-> 1)) <-> 2'); - to_tsquery -------------- - '1' <-> '2' -(1 row) - -SELECT to_tsquery('english', '((1 <-> a) <-> s) <-> 2'); - to_tsquery -------------- - '1' <3> '2' -(1 row) - -SELECT to_tsquery('english', '(s <-> (1 <-> a)) <-> 2'); - to_tsquery -------------- - '1' <2> '2' -(1 row) - -SELECT to_tsquery('english', '2 <-> ((a <-> 1) <-> s)'); - to_tsquery -------------- - '2' <2> '1' -(1 row) - -SELECT to_tsquery('english', '2 <-> (s <-> (a <-> 1))'); - to_tsquery -------------- - '2' <3> '1' -(1 row) - -SELECT to_tsquery('english', '2 <-> ((1 <-> a) <-> s)'); - to_tsquery -------------- - '2' <-> '1' -(1 row) - -SELECT to_tsquery('english', '2 <-> (s <-> (1 <-> a))'); - to_tsquery -------------- - '2' <2> '1' -(1 row) - -SELECT to_tsquery('english', 'foo <-> (a <-> (the <-> bar))'); - to_tsquery ------------------ - 'foo' <3> 'bar' -(1 row) - -SELECT to_tsquery('english', '((foo <-> a) <-> the) <-> bar'); - to_tsquery ------------------ - 'foo' <3> 'bar' -(1 row) - -SELECT to_tsquery('english', 'foo <-> a <-> the <-> bar'); - to_tsquery ------------------ - 'foo' <3> 'bar' -(1 row) - -SELECT phraseto_tsquery('english', 'PostgreSQL can be extended by the user in many ways'); - phraseto_tsquery ------------------------------------------------------------ - 'postgresql' <3> 'extend' <3> 'user' <2> 'mani' <-> 'way' -(1 row) - -SELECT ts_rank_cd(to_tsvector('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -'), to_tsquery('english', 'paint&water')); - ts_rank_cd ------------- - 0.05 -(1 row) - -SELECT ts_rank_cd(to_tsvector('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -'), to_tsquery('english', 'breath&motion&water')); - ts_rank_cd -------------- - 0.008333334 -(1 row) - -SELECT ts_rank_cd(to_tsvector('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -'), to_tsquery('english', 'ocean')); - ts_rank_cd ------------- - 0.1 -(1 row) - -SELECT ts_rank_cd(to_tsvector('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -'), to_tsquery('english', 'painted <-> Ship')); - ts_rank_cd ------------- - 0.1 -(1 row) - -SELECT ts_rank_cd(strip(to_tsvector('both stripped')), - to_tsquery('both & stripped')); - ts_rank_cd ------------- - 0 -(1 row) - -SELECT ts_rank_cd(to_tsvector('unstripped') || strip(to_tsvector('stripped')), - to_tsquery('unstripped & stripped')); - ts_rank_cd ------------- - 0 -(1 row) - ---headline tests -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'paint&water')); - ts_headline ------------------------------------------ - painted Ocean. + - Water, water, every where+ - And all the boards did shrink; + - Water, water, every -(1 row) - -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'breath&motion&water')); - ts_headline ----------------------------------- - breath nor motion,+ - As idle as a painted Ship + - Upon a painted Ocean. + - Water, water -(1 row) - -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'ocean')); - ts_headline ----------------------------------- - Ocean. + - Water, water, every where + - And all the boards did shrink;+ - Water, water, every where -(1 row) - -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', phraseto_tsquery('english', 'painted Ocean')); - ts_headline ---------------------------------------- - painted Ship + - Upon a painted Ocean.+ - Water, water, every where + - And all the boards did shrink -(1 row) - -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', phraseto_tsquery('english', 'idle as a painted Ship')); - ts_headline ---------------------------------------------- - idle as a painted Ship+ - Upon a painted Ocean. + - Water, water, every where + - And all the boards -(1 row) - -SELECT ts_headline('english', -'Lorem ipsum urna. Nullam nullam ullamcorper urna.', -to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), -'MaxWords=100, MinWords=1'); - ts_headline -------------------------------------------------------------------------------- - Lorem ipsum urna. Nullam nullam ullamcorper urna -(1 row) - -SELECT ts_headline('english', ' - - - -Sea view wow foo bar qq -YES   -ff-bg - - -', -to_tsquery('english', 'sea&foo'), 'HighlightAll=true'); - ts_headline ------------------------------------------------------------------------------ - + - + - + - + - Sea view wow foo bar qq + - YES  + - ff-bg + - + - + - -(1 row) - -SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=2, MinWords=1'); - ts_headline -------------------- - 1 3 -(1 row) - -SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 & 3', 'MaxWords=4, MinWords=1'); - ts_headline ---------------------- - 1 2 3 -(1 row) - -SELECT ts_headline('simple', '1 2 3 1 3'::text, '1 <-> 3', 'MaxWords=4, MinWords=1'); - ts_headline ----------------------------- - 3 1 3 -(1 row) - ---Check if headline fragments work -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'ocean'), 'MaxFragments=1'); - ts_headline ------------------------------------- - after day, + - We stuck, nor breath nor motion,+ - As idle as a painted Ship + - Upon a painted Ocean. + - Water, water, every where + - And all the boards did shrink; + - Water, water, every where, + - Nor any drop -(1 row) - ---Check if more than one fragments are displayed -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2'); - ts_headline ----------------------------------------------- - after day, day after day, + - We stuck, nor breath nor motion, + - As idle as a painted Ship + - Upon a painted Ocean. + - Water, water, every where + - And all the boards did shrink; + - Water, water, every where ... drop to drink.+ - S. T. Coleridge -(1 row) - ---Fragments when there all query words are not in the document -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1'); - ts_headline ------------------------------------- - + - Day after day, day after day, + - We stuck, nor breath nor motion,+ - As idle as -(1 row) - ---FragmentDelimiter option -SELECT ts_headline('english', ' -Day after day, day after day, - We stuck, nor breath nor motion, -As idle as a painted Ship - Upon a painted Ocean. -Water, water, every where - And all the boards did shrink; -Water, water, every where, - Nor any drop to drink. -S. T. Coleridge (1772-1834) -', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***'); - ts_headline --------------------------------------------- - after day, day after day, + - We stuck, nor breath nor motion, + - As idle as a painted Ship + - Upon a painted Ocean. + - Water, water, every where + - And all the boards did shrink; + - Water, water, every where***drop to drink.+ - S. T. Coleridge -(1 row) - ---Fragments with phrase search -SELECT ts_headline('english', -'Lorem ipsum urna. Nullam nullam ullamcorper urna.', -to_tsquery('english','Lorem') && phraseto_tsquery('english','ullamcorper urna'), -'MaxFragments=100, MaxWords=100, MinWords=1'); - ts_headline -------------------------------------------------------------------------------- - Lorem ipsum urna. Nullam nullam ullamcorper urna -(1 row) - ---Rewrite sub system -CREATE TABLE test_tsquery (txtkeyword TEXT, txtsample TEXT); -\set ECHO none -ALTER TABLE test_tsquery ADD COLUMN keyword tsquery; -UPDATE test_tsquery SET keyword = to_tsquery('english', txtkeyword); -ALTER TABLE test_tsquery ADD COLUMN sample tsquery; -UPDATE test_tsquery SET sample = to_tsquery('english', txtsample::text); -SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york'; - count -------- - 2 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york'; - count -------- - 3 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york'; - count -------- - 1 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york'; - count -------- - 4 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york'; - count -------- - 3 -(1 row) - -CREATE UNIQUE INDEX bt_tsq ON test_tsquery (keyword); -SET enable_seqscan=OFF; -SELECT COUNT(*) FROM test_tsquery WHERE keyword < 'new & york'; - count -------- - 2 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword <= 'new & york'; - count -------- - 3 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword = 'new & york'; - count -------- - 1 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword >= 'new & york'; - count -------- - 4 -(1 row) - -SELECT COUNT(*) FROM test_tsquery WHERE keyword > 'new & york'; - count -------- - 3 -(1 row) - -RESET enable_seqscan; -SELECT ts_rewrite('foo & bar & qq & new & york', 'new & york'::tsquery, 'big & apple | nyc | new & york & city'); - ts_rewrite ------------------------------------------------------------------------------- - 'foo' & 'bar' & 'qq' & ( 'city' & 'new' & 'york' | 'nyc' | 'big' & 'apple' ) -(1 row) - -SELECT ts_rewrite(ts_rewrite('new & !york ', 'york', '!jersey'), - 'jersey', 'mexico'); - ts_rewrite --------------------- - 'new' & !!'mexico' -(1 row) - -SELECT ts_rewrite('moscow', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite('moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite('bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -SELECT ts_rewrite( 'moscow', 'SELECT keyword, sample FROM test_tsquery'); - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite( 'moscow & hotel', 'SELECT keyword, sample FROM test_tsquery'); - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite( 'bar & new & qq & foo & york', 'SELECT keyword, sample FROM test_tsquery'); - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -SELECT ts_rewrite('1 & (2 <-> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite -------------- - '2' <-> '4' -(1 row) - -SELECT ts_rewrite('1 & (2 <2> 3)', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite -------------------- - '1' & '2' <2> '3' -(1 row) - -SELECT ts_rewrite('5 <-> (1 & (2 <-> 3))', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite -------------------------- - '5' <-> ( '2' <-> '4' ) -(1 row) - -SELECT ts_rewrite('5 <-> (6 | 8)', 'SELECT keyword, sample FROM test_tsquery'::text ); - ts_rewrite ------------------------ - '5' <-> ( '6' | '8' ) -(1 row) - --- Check empty substitution -SELECT ts_rewrite(to_tsquery('5 & (6 | 5)'), to_tsquery('5'), to_tsquery('')); -NOTICE: text-search query doesn't contain lexemes: "" - ts_rewrite ------------- - '6' -(1 row) - -SELECT ts_rewrite(to_tsquery('!5'), to_tsquery('5'), to_tsquery('')); -NOTICE: text-search query doesn't contain lexemes: "" - ts_rewrite ------------- - -(1 row) - -SELECT keyword FROM test_tsquery WHERE keyword @> 'new'; - keyword ----------------- - 'new' & 'york' -(1 row) - -SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'; - keyword ----------- - 'moscow' -(1 row) - -SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'; - keyword ---------- -(0 rows) - -SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'; - keyword ----------- - 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query; - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query; - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -CREATE INDEX qq ON test_tsquery USING gist (keyword tsquery_ops); -SET enable_seqscan=OFF; -SELECT keyword FROM test_tsquery WHERE keyword @> 'new'; - keyword ----------------- - 'new' & 'york' -(1 row) - -SELECT keyword FROM test_tsquery WHERE keyword @> 'moscow'; - keyword ----------- - 'moscow' -(1 row) - -SELECT keyword FROM test_tsquery WHERE keyword <@ 'new'; - keyword ---------- -(0 rows) - -SELECT keyword FROM test_tsquery WHERE keyword <@ 'moscow'; - keyword ----------- - 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query; - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow') AS query; - ts_rewrite ---------------------- - 'moskva' | 'moscow' -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'moscow & hotel') AS query; - ts_rewrite ------------------------------------ - 'hotel' & ( 'moskva' | 'moscow' ) -(1 row) - -SELECT ts_rewrite( query, 'SELECT keyword, sample FROM test_tsquery' ) FROM to_tsquery('english', 'bar & new & qq & foo & york') AS query; - ts_rewrite ---------------------------------------------------------------------------------- - 'citi' & 'foo' & ( 'bar' | 'qq' ) & ( 'nyc' | 'big' & 'appl' | 'new' & 'york' ) -(1 row) - -SELECT ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); - ts_rewrite ------------------------------------------ - ( 'bar' | 'baz' ) <-> ( 'bar' | 'baz' ) -(1 row) - -SELECT to_tsvector('foo bar') @@ - ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); - ?column? ----------- - f -(1 row) - -SELECT to_tsvector('bar baz') @@ - ts_rewrite(tsquery_phrase('foo', 'foo'), 'foo', 'bar | baz'); - ?column? ----------- - t -(1 row) - -RESET enable_seqscan; ---test GUC -SET default_text_search_config=simple; -SELECT to_tsvector('SKIES My booKs'); - to_tsvector ----------------------------- - 'books':3 'my':2 'skies':1 -(1 row) - -SELECT plainto_tsquery('SKIES My booKs'); - plainto_tsquery --------------------------- - 'skies' & 'my' & 'books' -(1 row) - -SELECT to_tsquery('SKIES & My | booKs'); - to_tsquery --------------------------- - 'skies' & 'my' | 'books' -(1 row) - -SET default_text_search_config=english; -SELECT to_tsvector('SKIES My booKs'); - to_tsvector ------------------- - 'book':3 'sky':1 -(1 row) - -SELECT plainto_tsquery('SKIES My booKs'); - plainto_tsquery ------------------ - 'sky' & 'book' -(1 row) - -SELECT to_tsquery('SKIES & My | booKs'); - to_tsquery ----------------- - 'sky' | 'book' -(1 row) - ---trigger -CREATE TRIGGER tsvectorupdate -BEFORE UPDATE OR INSERT ON test_tsvector -FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(a, 'pg_catalog.english', t); -SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); - count -------- - 0 -(1 row) - -INSERT INTO test_tsvector (t) VALUES ('345 qwerty'); -SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); - count -------- - 1 -(1 row) - -UPDATE test_tsvector SET t = null WHERE t = '345 qwerty'; -SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); - count -------- - 0 -(1 row) - -INSERT INTO test_tsvector (t) VALUES ('345 qwerty'); -SELECT count(*) FROM test_tsvector WHERE a @@ to_tsquery('345&qwerty'); - count -------- - 1 -(1 row) - --- Test inlining of immutable constant functions --- to_tsquery(text) is not immutable, so it won't be inlined -explain (costs off) -select * from test_tsquery, to_tsquery('new') q where txtsample @@ q; - QUERY PLAN ------------------------------------------------- - Nested Loop - Join Filter: (test_tsquery.txtsample @@ q.q) - -> Function Scan on to_tsquery q - -> Seq Scan on test_tsquery -(4 rows) - --- to_tsquery(regconfig, text) is an immutable function. --- That allows us to get rid of using function scan and join at all. -explain (costs off) -select * from test_tsquery, to_tsquery('english', 'new') q where txtsample @@ q; - QUERY PLAN ---------------------------------------------- - Seq Scan on test_tsquery - Filter: (txtsample @@ '''new'''::tsquery) -(2 rows) - --- test finding items in GIN's pending list -create temp table pendtest (ts tsvector); -create index pendtest_idx on pendtest using gin(ts); -insert into pendtest values (to_tsvector('Lore ipsam')); -insert into pendtest values (to_tsvector('Lore ipsum')); -select * from pendtest where 'ipsu:*'::tsquery @@ ts; - ts --------------------- - 'ipsum':2 'lore':1 -(1 row) - -select * from pendtest where 'ipsa:*'::tsquery @@ ts; - ts --------------------- - 'ipsam':2 'lore':1 -(1 row) - -select * from pendtest where 'ips:*'::tsquery @@ ts; - ts --------------------- - 'ipsam':2 'lore':1 - 'ipsum':2 'lore':1 -(2 rows) - -select * from pendtest where 'ipt:*'::tsquery @@ ts; - ts ----- -(0 rows) - -select * from pendtest where 'ipi:*'::tsquery @@ ts; - ts ----- -(0 rows) - ---check OP_PHRASE on index -create temp table phrase_index_test(fts tsvector); -insert into phrase_index_test values ('A fat cat has just eaten a rat.'); -insert into phrase_index_test values (to_tsvector('english', 'A fat cat has just eaten a rat.')); -create index phrase_index_test_idx on phrase_index_test using gin(fts); -set enable_seqscan = off; -select * from phrase_index_test where fts @@ phraseto_tsquery('english', 'fat cat'); - fts ------------------------------------ - 'cat':3 'eaten':6 'fat':2 'rat':8 -(1 row) - -set enable_seqscan = on; --- test websearch_to_tsquery function -select websearch_to_tsquery('simple', 'I have a fat:*ABCD cat'); - websearch_to_tsquery ---------------------------------------------- - 'i' & 'have' & 'a' & 'fat' & 'abcd' & 'cat' -(1 row) - -select websearch_to_tsquery('simple', 'orange:**AABBCCDD'); - websearch_to_tsquery ------------------------ - 'orange' & 'aabbccdd' -(1 row) - -select websearch_to_tsquery('simple', 'fat:A!cat:B|rat:C<'); - websearch_to_tsquery ------------------------------------------ - 'fat' & 'a' & 'cat' & 'b' & 'rat' & 'c' -(1 row) - -select websearch_to_tsquery('simple', 'fat:A : cat:B'); - websearch_to_tsquery ---------------------------- - 'fat' & 'a' & 'cat' & 'b' -(1 row) - -select websearch_to_tsquery('simple', 'fat*rat'); - websearch_to_tsquery ----------------------- - 'fat' & 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat-rat'); - websearch_to_tsquery ---------------------------- - 'fat-rat' & 'fat' & 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat_rat'); - websearch_to_tsquery ----------------------- - 'fat' & 'rat' -(1 row) - --- weights are completely ignored -select websearch_to_tsquery('simple', 'abc : def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('simple', 'abc:def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('simple', 'a:::b'); - websearch_to_tsquery ----------------------- - 'a' & 'b' -(1 row) - -select websearch_to_tsquery('simple', 'abc:d'); - websearch_to_tsquery ----------------------- - 'abc' & 'd' -(1 row) - -select websearch_to_tsquery('simple', ':'); -NOTICE: text-search query contains only stop words or doesn't contain lexemes, ignored - websearch_to_tsquery ----------------------- - -(1 row) - --- these operators are ignored -select websearch_to_tsquery('simple', 'abc & def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('simple', 'abc | def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('simple', 'abc <-> def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('simple', 'abc (pg or class)'); - websearch_to_tsquery ------------------------- - 'abc' & 'pg' | 'class' -(1 row) - --- NOT is ignored in quotes -select websearch_to_tsquery('english', 'My brand new smartphone'); - websearch_to_tsquery -------------------------------- - 'brand' & 'new' & 'smartphon' -(1 row) - -select websearch_to_tsquery('english', 'My brand "new smartphone"'); - websearch_to_tsquery ---------------------------------- - 'brand' & 'new' <-> 'smartphon' -(1 row) - -select websearch_to_tsquery('english', 'My brand "new -smartphone"'); - websearch_to_tsquery ---------------------------------- - 'brand' & 'new' <-> 'smartphon' -(1 row) - --- test OR operator -select websearch_to_tsquery('simple', 'cat or rat'); - websearch_to_tsquery ----------------------- - 'cat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'cat OR rat'); - websearch_to_tsquery ----------------------- - 'cat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'cat "OR" rat'); - websearch_to_tsquery ----------------------- - 'cat' & 'or' & 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'cat OR'); - websearch_to_tsquery ----------------------- - 'cat' & 'or' -(1 row) - -select websearch_to_tsquery('simple', 'OR rat'); - websearch_to_tsquery ----------------------- - 'or' & 'rat' -(1 row) - -select websearch_to_tsquery('simple', '"fat cat OR rat"'); - websearch_to_tsquery ------------------------------------- - 'fat' <-> 'cat' <-> 'or' <-> 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat (cat OR rat'); - websearch_to_tsquery ------------------------ - 'fat' & 'cat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'or OR or'); - websearch_to_tsquery ----------------------- - 'or' | 'or' -(1 row) - --- OR is an operator here ... -select websearch_to_tsquery('simple', '"fat cat"or"fat rat"'); - websearch_to_tsquery ------------------------------------ - 'fat' <-> 'cat' | 'fat' <-> 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or(rat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or)rat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or&rat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or|rat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or!rat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat orrat'); - websearch_to_tsquery ----------------------- - 'fat' | 'rat' -(1 row) - -select websearch_to_tsquery('simple', 'fat or '); - websearch_to_tsquery ----------------------- - 'fat' & 'or' -(1 row) - --- ... but not here -select websearch_to_tsquery('simple', 'abc orange'); - websearch_to_tsquery ----------------------- - 'abc' & 'orange' -(1 row) - -select websearch_to_tsquery('simple', 'abc OR1234'); - websearch_to_tsquery ----------------------- - 'abc' & 'or1234' -(1 row) - -select websearch_to_tsquery('simple', 'abc or-abc'); - websearch_to_tsquery ---------------------------------- - 'abc' & 'or-abc' & 'or' & 'abc' -(1 row) - -select websearch_to_tsquery('simple', 'abc OR_abc'); - websearch_to_tsquery ----------------------- - 'abc' & 'or' & 'abc' -(1 row) - --- test quotes -select websearch_to_tsquery('english', '"pg_class pg'); - websearch_to_tsquery ------------------------ - 'pg' & 'class' & 'pg' -(1 row) - -select websearch_to_tsquery('english', 'pg_class pg"'); - websearch_to_tsquery ------------------------ - 'pg' & 'class' & 'pg' -(1 row) - -select websearch_to_tsquery('english', '"pg_class pg"'); - websearch_to_tsquery ------------------------------ - ( 'pg' & 'class' ) <-> 'pg' -(1 row) - -select websearch_to_tsquery('english', 'abc "pg_class pg"'); - websearch_to_tsquery -------------------------------------- - 'abc' & ( 'pg' & 'class' ) <-> 'pg' -(1 row) - -select websearch_to_tsquery('english', '"pg_class pg" def'); - websearch_to_tsquery -------------------------------------- - ( 'pg' & 'class' ) <-> 'pg' & 'def' -(1 row) - -select websearch_to_tsquery('english', 'abc "pg pg_class pg" def'); - websearch_to_tsquery ------------------------------------------------------- - 'abc' & 'pg' <-> ( 'pg' & 'class' ) <-> 'pg' & 'def' -(1 row) - -select websearch_to_tsquery('english', ' or "pg pg_class pg" or '); - websearch_to_tsquery --------------------------------------- - 'pg' <-> ( 'pg' & 'class' ) <-> 'pg' -(1 row) - -select websearch_to_tsquery('english', '""pg pg_class pg""'); - websearch_to_tsquery ------------------------------- - 'pg' & 'pg' & 'class' & 'pg' -(1 row) - -select websearch_to_tsquery('english', 'abc """"" def'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('english', 'cat -"fat rat"'); - websearch_to_tsquery ------------------------------- - 'cat' & !( 'fat' <-> 'rat' ) -(1 row) - -select websearch_to_tsquery('english', 'cat -"fat rat" cheese'); - websearch_to_tsquery ----------------------------------------- - 'cat' & !( 'fat' <-> 'rat' ) & 'chees' -(1 row) - -select websearch_to_tsquery('english', 'abc "def -"'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('english', 'abc "def :"'); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('english', '"A fat cat" has just eaten a -rat.'); - websearch_to_tsquery ------------------------------------- - 'fat' <-> 'cat' & 'eaten' & !'rat' -(1 row) - -select websearch_to_tsquery('english', '"A fat cat" has just eaten OR !rat.'); - websearch_to_tsquery ------------------------------------ - 'fat' <-> 'cat' & 'eaten' | 'rat' -(1 row) - -select websearch_to_tsquery('english', '"A fat cat" has just (+eaten OR -rat)'); - websearch_to_tsquery ------------------------------------- - 'fat' <-> 'cat' & 'eaten' | !'rat' -(1 row) - -select websearch_to_tsquery('english', 'this is ----fine'); - websearch_to_tsquery ----------------------- - !!!!'fine' -(1 row) - -select websearch_to_tsquery('english', '(()) )))) this ||| is && -fine, "dear friend" OR good'); - websearch_to_tsquery ----------------------------------------- - !'fine' & 'dear' <-> 'friend' | 'good' -(1 row) - -select websearch_to_tsquery('english', 'an old <-> cat " is fine &&& too'); - websearch_to_tsquery ------------------------- - 'old' & 'cat' & 'fine' -(1 row) - -select websearch_to_tsquery('english', '"A the" OR just on'); -NOTICE: text-search query contains only stop words or doesn't contain lexemes, ignored - websearch_to_tsquery ----------------------- - -(1 row) - -select websearch_to_tsquery('english', '"a fat cat" ate a rat'); - websearch_to_tsquery ---------------------------------- - 'fat' <-> 'cat' & 'ate' & 'rat' -(1 row) - -select to_tsvector('english', 'A fat cat ate a rat') @@ - websearch_to_tsquery('english', '"a fat cat" ate a rat'); - ?column? ----------- - t -(1 row) - -select to_tsvector('english', 'A fat grey cat ate a rat') @@ - websearch_to_tsquery('english', '"a fat cat" ate a rat'); - ?column? ----------- - f -(1 row) - --- cases handled by gettoken_tsvector() -select websearch_to_tsquery(''''); -NOTICE: text-search query contains only stop words or doesn't contain lexemes, ignored - websearch_to_tsquery ----------------------- - -(1 row) - -select websearch_to_tsquery('''abc''''def'''); - websearch_to_tsquery ----------------------- - 'abc' & 'def' -(1 row) - -select websearch_to_tsquery('\abc'); - websearch_to_tsquery ----------------------- - 'abc' -(1 row) - -select websearch_to_tsquery('\'); -NOTICE: text-search query contains only stop words or doesn't contain lexemes, ignored - websearch_to_tsquery ----------------------- - -(1 row) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rangefuncs.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/rangefuncs.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/rangefuncs.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/rangefuncs.out 2022-02-13 01:13:23.675618052 +0100 @@ -1404,1031 +1404,8 @@ ) AS ss1 ON TRUE FULL JOIN generate_series(1, v1.r1) AS gs4 ON FALSE ) AS ss0 ON TRUE; - r1 | gs1 | gs2 | gs3 | gs4 -----+-----+-----+-----+----- - 1 | | | | 1 - 1 | 1 | 1 | 1 | - 2 | | | | 1 - 2 | | | | 2 - 2 | 1 | 1 | 1 | - 2 | 2 | 1 | 1 | - 2 | 2 | 2 | 1 | - 2 | 2 | 2 | 2 | -(8 rows) - -DROP FUNCTION rngfunc_sql(int,int); -DROP FUNCTION rngfunc_mat(int,int); -DROP SEQUENCE rngfunc_rescan_seq1; -DROP SEQUENCE rngfunc_rescan_seq2; --- --- Test cases involving OUT parameters --- -CREATE FUNCTION rngfunc(in f1 int, out f2 int) -AS 'select $1+1' LANGUAGE sql; -SELECT rngfunc(42); - rngfunc ---------- - 43 -(1 row) - -SELECT * FROM rngfunc(42); - f2 ----- - 43 -(1 row) - -SELECT * FROM rngfunc(42) AS p(x); - x ----- - 43 -(1 row) - --- explicit spec of return type is OK -CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS int -AS 'select $1+1' LANGUAGE sql; --- error, wrong result type -CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int) RETURNS float -AS 'select $1+1' LANGUAGE sql; -ERROR: function result type must be integer because of OUT parameters --- with multiple OUT params you must get a RECORD result -CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) RETURNS int -AS 'select $1+1' LANGUAGE sql; -ERROR: function result type must be record because of OUT parameters -CREATE OR REPLACE FUNCTION rngfunc(in f1 int, out f2 int, out f3 text) -RETURNS record -AS 'select $1+1' LANGUAGE sql; -ERROR: cannot change return type of existing function -HINT: Use DROP FUNCTION rngfunc(integer) first. -CREATE OR REPLACE FUNCTION rngfuncr(in f1 int, out f2 int, out text) -AS $$select $1-1, $1::text || 'z'$$ LANGUAGE sql; -SELECT f1, rngfuncr(f1) FROM int4_tbl; - f1 | rngfuncr --------------+---------------------------- - 0 | (-1,0z) - 123456 | (123455,123456z) - -123456 | (-123457,-123456z) - 2147483647 | (2147483646,2147483647z) - -2147483647 | (-2147483648,-2147483647z) -(5 rows) - -SELECT * FROM rngfuncr(42); - f2 | column2 -----+--------- - 41 | 42z -(1 row) - -SELECT * FROM rngfuncr(42) AS p(a,b); - a | b -----+----- - 41 | 42z -(1 row) - -CREATE OR REPLACE FUNCTION rngfuncb(in f1 int, inout f2 int, out text) -AS $$select $2-1, $1::text || 'z'$$ LANGUAGE sql; -SELECT f1, rngfuncb(f1, f1/2) FROM int4_tbl; - f1 | rngfuncb --------------+---------------------------- - 0 | (-1,0z) - 123456 | (61727,123456z) - -123456 | (-61729,-123456z) - 2147483647 | (1073741822,2147483647z) - -2147483647 | (-1073741824,-2147483647z) -(5 rows) - -SELECT * FROM rngfuncb(42, 99); - f2 | column2 -----+--------- - 98 | 42z -(1 row) - -SELECT * FROM rngfuncb(42, 99) AS p(a,b); - a | b -----+----- - 98 | 42z -(1 row) - --- Can reference function with or without OUT params for DROP, etc -DROP FUNCTION rngfunc(int); -DROP FUNCTION rngfuncr(in f2 int, out f1 int, out text); -DROP FUNCTION rngfuncb(in f1 int, inout f2 int); --- --- For my next trick, polymorphic OUT parameters --- -CREATE FUNCTION dup (f1 anyelement, f2 out anyelement, f3 out anyarray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; -SELECT dup(22); - dup ----------------- - (22,"{22,22}") -(1 row) - -SELECT dup('xyz'); -- fails -ERROR: could not determine polymorphic type because input has type unknown -SELECT dup('xyz'::text); - dup -------------------- - (xyz,"{xyz,xyz}") -(1 row) - -SELECT * FROM dup('xyz'::text); - f2 | f3 ------+----------- - xyz | {xyz,xyz} -(1 row) - --- fails, as we are attempting to rename first argument -CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; -ERROR: cannot change name of input parameter "f1" -HINT: Use DROP FUNCTION dup(anyelement) first. -DROP FUNCTION dup(anyelement); --- equivalent behavior, though different name exposed for input arg -CREATE OR REPLACE FUNCTION dup (inout f2 anyelement, out f3 anyarray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; -SELECT dup(22); - dup ----------------- - (22,"{22,22}") -(1 row) - -DROP FUNCTION dup(anyelement); --- fails, no way to deduce outputs -CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; -ERROR: cannot determine result data type -DETAIL: A result of type anyelement requires at least one input of type anyelement, anyarray, anynonarray, anyenum, or anyrange. -CREATE FUNCTION dup (f1 anycompatible, f2 anycompatiblearray, f3 out anycompatible, f4 out anycompatiblearray) -AS 'select $1, $2' LANGUAGE sql; -SELECT dup(22, array[44]); - dup ------------ - (22,{44}) -(1 row) - -SELECT dup(4.5, array[44]); - dup ------------- - (4.5,{44}) -(1 row) - -SELECT dup(22, array[44::bigint]); - dup ------------ - (22,{44}) -(1 row) - -SELECT *, pg_typeof(f3), pg_typeof(f4) FROM dup(22, array[44::bigint]); - f3 | f4 | pg_typeof | pg_typeof -----+------+-----------+----------- - 22 | {44} | bigint | bigint[] -(1 row) - -DROP FUNCTION dup(f1 anycompatible, f2 anycompatiblearray); -CREATE FUNCTION dup (f1 anycompatiblerange, f2 out anycompatible, f3 out anycompatiblearray, f4 out anycompatiblerange) -AS 'select lower($1), array[lower($1), upper($1)], $1' LANGUAGE sql; -SELECT dup(int4range(4,7)); - dup ---------------------- - (4,"{4,7}","[4,7)") -(1 row) - -SELECT dup(numrange(4,7)); - dup ---------------------- - (4,"{4,7}","[4,7)") -(1 row) - -SELECT dup(textrange('aaa', 'bbb')); - dup -------------------------------- - (aaa,"{aaa,bbb}","[aaa,bbb)") -(1 row) - -DROP FUNCTION dup(f1 anycompatiblerange); --- fails, no way to deduce outputs -CREATE FUNCTION bad (f1 anyarray, out f2 anycompatible, out f3 anycompatiblearray) -AS 'select $1, array[$1,$1]' LANGUAGE sql; -ERROR: cannot determine result data type -DETAIL: A result of type anycompatible requires at least one input of type anycompatible, anycompatiblearray, anycompatiblenonarray, or anycompatiblerange. --- --- table functions --- -CREATE OR REPLACE FUNCTION rngfunc() -RETURNS TABLE(a int) -AS $$ SELECT a FROM generate_series(1,5) a(a) $$ LANGUAGE sql; -SELECT * FROM rngfunc(); - a ---- - 1 - 2 - 3 - 4 - 5 -(5 rows) - -DROP FUNCTION rngfunc(); -CREATE OR REPLACE FUNCTION rngfunc(int) -RETURNS TABLE(a int, b int) -AS $$ SELECT a, b - FROM generate_series(1,$1) a(a), - generate_series(1,$1) b(b) $$ LANGUAGE sql; -SELECT * FROM rngfunc(3); - a | b ----+--- - 1 | 1 - 1 | 2 - 1 | 3 - 2 | 1 - 2 | 2 - 2 | 3 - 3 | 1 - 3 | 2 - 3 | 3 -(9 rows) - -DROP FUNCTION rngfunc(int); --- case that causes change of typmod knowledge during inlining -CREATE OR REPLACE FUNCTION rngfunc() -RETURNS TABLE(a varchar(5)) -AS $$ SELECT 'hello'::varchar(5) $$ LANGUAGE sql STABLE; -SELECT * FROM rngfunc() GROUP BY 1; - a -------- - hello -(1 row) - -DROP FUNCTION rngfunc(); --- --- some tests on SQL functions with RETURNING --- -create temp table tt(f1 serial, data text); -create function insert_tt(text) returns int as -$$ insert into tt(data) values($1) returning f1 $$ -language sql; -select insert_tt('foo'); - insert_tt ------------ - 1 -(1 row) - -select insert_tt('bar'); - insert_tt ------------ - 2 -(1 row) - -select * from tt; - f1 | data -----+------ - 1 | foo - 2 | bar -(2 rows) - --- insert will execute to completion even if function needs just 1 row -create or replace function insert_tt(text) returns int as -$$ insert into tt(data) values($1),($1||$1) returning f1 $$ -language sql; -select insert_tt('fool'); - insert_tt ------------ - 3 -(1 row) - -select * from tt; - f1 | data -----+---------- - 1 | foo - 2 | bar - 3 | fool - 4 | foolfool -(4 rows) - --- setof does what's expected -create or replace function insert_tt2(text,text) returns setof int as -$$ insert into tt(data) values($1),($2) returning f1 $$ -language sql; -select insert_tt2('foolish','barrish'); - insert_tt2 ------------- - 5 - 6 -(2 rows) - -select * from insert_tt2('baz','quux'); - insert_tt2 ------------- - 7 - 8 -(2 rows) - -select * from tt; - f1 | data -----+---------- - 1 | foo - 2 | bar - 3 | fool - 4 | foolfool - 5 | foolish - 6 | barrish - 7 | baz - 8 | quux -(8 rows) - --- limit doesn't prevent execution to completion -select insert_tt2('foolish','barrish') limit 1; - insert_tt2 ------------- - 9 -(1 row) - -select * from tt; - f1 | data -----+---------- - 1 | foo - 2 | bar - 3 | fool - 4 | foolfool - 5 | foolish - 6 | barrish - 7 | baz - 8 | quux - 9 | foolish - 10 | barrish -(10 rows) - --- triggers will fire, too -create function noticetrigger() returns trigger as $$ -begin - raise notice 'noticetrigger % %', new.f1, new.data; - return null; -end $$ language plpgsql; -create trigger tnoticetrigger after insert on tt for each row -execute procedure noticetrigger(); -select insert_tt2('foolme','barme') limit 1; -NOTICE: noticetrigger 11 foolme -NOTICE: noticetrigger 12 barme - insert_tt2 ------------- - 11 -(1 row) - -select * from tt; - f1 | data -----+---------- - 1 | foo - 2 | bar - 3 | fool - 4 | foolfool - 5 | foolish - 6 | barrish - 7 | baz - 8 | quux - 9 | foolish - 10 | barrish - 11 | foolme - 12 | barme -(12 rows) - --- and rules work -create temp table tt_log(f1 int, data text); -create rule insert_tt_rule as on insert to tt do also - insert into tt_log values(new.*); -select insert_tt2('foollog','barlog') limit 1; -NOTICE: noticetrigger 13 foollog -NOTICE: noticetrigger 14 barlog - insert_tt2 ------------- - 13 -(1 row) - -select * from tt; - f1 | data -----+---------- - 1 | foo - 2 | bar - 3 | fool - 4 | foolfool - 5 | foolish - 6 | barrish - 7 | baz - 8 | quux - 9 | foolish - 10 | barrish - 11 | foolme - 12 | barme - 13 | foollog - 14 | barlog -(14 rows) - --- note that nextval() gets executed a second time in the rule expansion, --- which is expected. -select * from tt_log; - f1 | data -----+--------- - 15 | foollog - 16 | barlog -(2 rows) - --- test case for a whole-row-variable bug -create function rngfunc1(n integer, out a text, out b text) - returns setof record - language sql - as $$ select 'foo ' || i, 'bar ' || i from generate_series(1,$1) i $$; -set work_mem='64kB'; -select t.a, t, t.a from rngfunc1(10000) t limit 1; - a | t | a --------+-------------------+------- - foo 1 | ("foo 1","bar 1") | foo 1 -(1 row) - -reset work_mem; -select t.a, t, t.a from rngfunc1(10000) t limit 1; - a | t | a --------+-------------------+------- - foo 1 | ("foo 1","bar 1") | foo 1 -(1 row) - -drop function rngfunc1(n integer); --- test use of SQL functions returning record --- this is supported in some cases where the query doesn't specify --- the actual record type ... -create function array_to_set(anyarray) returns setof record as $$ - select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i -$$ language sql strict immutable; -select array_to_set(array['one', 'two']); - array_to_set --------------- - (1,one) - (2,two) -(2 rows) - -select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text); - f1 | f2 -----+----- - 1 | one - 2 | two -(2 rows) - -select * from array_to_set(array['one', 'two']); -- fail -ERROR: a column definition list is required for functions returning "record" -LINE 1: select * from array_to_set(array['one', 'two']); - ^ --- after-the-fact coercion of the columns is now possible, too -select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); - f1 | f2 -------+----- - 1.00 | one - 2.00 | two -(2 rows) - --- and if it doesn't work, you get a compile-time not run-time error -select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text); -ERROR: return type mismatch in function declared to return record -DETAIL: Final statement returns integer instead of point at column 1. -CONTEXT: SQL function "array_to_set" during startup --- with "strict", this function can't be inlined in FROM -explain (verbose, costs off) - select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); - QUERY PLAN ----------------------------------------------------- - Function Scan on public.array_to_set t - Output: f1, f2 - Function Call: array_to_set('{one,two}'::text[]) -(3 rows) - --- but without, it can be: -create or replace function array_to_set(anyarray) returns setof record as $$ - select i AS "index", $1[i] AS "value" from generate_subscripts($1, 1) i -$$ language sql immutable; -select array_to_set(array['one', 'two']); - array_to_set --------------- - (1,one) - (2,two) -(2 rows) - -select * from array_to_set(array['one', 'two']) as t(f1 int,f2 text); - f1 | f2 -----+----- - 1 | one - 2 | two -(2 rows) - -select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); - f1 | f2 -------+----- - 1.00 | one - 2.00 | two -(2 rows) - -select * from array_to_set(array['one', 'two']) as t(f1 point,f2 text); -ERROR: return type mismatch in function declared to return record -DETAIL: Final statement returns integer instead of point at column 1. -CONTEXT: SQL function "array_to_set" during inlining -explain (verbose, costs off) - select * from array_to_set(array['one', 'two']) as t(f1 numeric(4,2),f2 text); - QUERY PLAN --------------------------------------------------------------- - Function Scan on pg_catalog.generate_subscripts i - Output: i.i, ('{one,two}'::text[])[i.i] - Function Call: generate_subscripts('{one,two}'::text[], 1) -(3 rows) - -create temp table rngfunc(f1 int8, f2 int8); -create function testrngfunc() returns record as $$ - insert into rngfunc values (1,2) returning *; -$$ language sql; -select testrngfunc(); - testrngfunc -------------- - (1,2) -(1 row) - -select * from testrngfunc() as t(f1 int8,f2 int8); - f1 | f2 -----+---- - 1 | 2 -(1 row) - -select * from testrngfunc(); -- fail -ERROR: a column definition list is required for functions returning "record" -LINE 1: select * from testrngfunc(); - ^ -drop function testrngfunc(); -create function testrngfunc() returns setof record as $$ - insert into rngfunc values (1,2), (3,4) returning *; -$$ language sql; -select testrngfunc(); - testrngfunc -------------- - (1,2) - (3,4) -(2 rows) - -select * from testrngfunc() as t(f1 int8,f2 int8); - f1 | f2 -----+---- - 1 | 2 - 3 | 4 -(2 rows) - -select * from testrngfunc(); -- fail -ERROR: a column definition list is required for functions returning "record" -LINE 1: select * from testrngfunc(); - ^ -drop function testrngfunc(); --- Check that typmod imposed by a composite type is honored -create type rngfunc_type as (f1 numeric(35,6), f2 numeric(35,2)); -create function testrngfunc() returns rngfunc_type as $$ - select 7.136178319899999964, 7.136178319899999964; -$$ language sql immutable; -explain (verbose, costs off) -select testrngfunc(); - QUERY PLAN -------------------------------------------- - Result - Output: '(7.136178,7.14)'::rngfunc_type -(2 rows) - -select testrngfunc(); - testrngfunc ------------------ - (7.136178,7.14) -(1 row) - -explain (verbose, costs off) -select * from testrngfunc(); - QUERY PLAN --------------------------------------------------- - Function Scan on testrngfunc - Output: f1, f2 - Function Call: '(7.136178,7.14)'::rngfunc_type -(3 rows) - -select * from testrngfunc(); - f1 | f2 -----------+------ - 7.136178 | 7.14 -(1 row) - -create or replace function testrngfunc() returns rngfunc_type as $$ - select 7.136178319899999964, 7.136178319899999964; -$$ language sql volatile; -explain (verbose, costs off) -select testrngfunc(); - QUERY PLAN -------------------------- - Result - Output: testrngfunc() -(2 rows) - -select testrngfunc(); - testrngfunc ------------------ - (7.136178,7.14) -(1 row) - -explain (verbose, costs off) -select * from testrngfunc(); - QUERY PLAN -------------------------------------- - Function Scan on public.testrngfunc - Output: f1, f2 - Function Call: testrngfunc() -(3 rows) - -select * from testrngfunc(); - f1 | f2 -----------+------ - 7.136178 | 7.14 -(1 row) - -drop function testrngfunc(); -create function testrngfunc() returns setof rngfunc_type as $$ - select 7.136178319899999964, 7.136178319899999964; -$$ language sql immutable; -explain (verbose, costs off) -select testrngfunc(); - QUERY PLAN -------------------------- - ProjectSet - Output: testrngfunc() - -> Result -(3 rows) - -select testrngfunc(); - testrngfunc ------------------ - (7.136178,7.14) -(1 row) - -explain (verbose, costs off) -select * from testrngfunc(); - QUERY PLAN --------------------------------------------------------- - Result - Output: 7.136178::numeric(35,6), 7.14::numeric(35,2) -(2 rows) - -select * from testrngfunc(); - f1 | f2 -----------+------ - 7.136178 | 7.14 -(1 row) - -create or replace function testrngfunc() returns setof rngfunc_type as $$ - select 7.136178319899999964, 7.136178319899999964; -$$ language sql volatile; -explain (verbose, costs off) -select testrngfunc(); - QUERY PLAN -------------------------- - ProjectSet - Output: testrngfunc() - -> Result -(3 rows) - -select testrngfunc(); - testrngfunc ------------------ - (7.136178,7.14) -(1 row) - -explain (verbose, costs off) -select * from testrngfunc(); - QUERY PLAN -------------------------------------- - Function Scan on public.testrngfunc - Output: f1, f2 - Function Call: testrngfunc() -(3 rows) - -select * from testrngfunc(); - f1 | f2 -----------+------ - 7.136178 | 7.14 -(1 row) - -create or replace function testrngfunc() returns setof rngfunc_type as $$ - select 1, 2 union select 3, 4 order by 1; -$$ language sql immutable; -explain (verbose, costs off) -select testrngfunc(); - QUERY PLAN -------------------------- - ProjectSet - Output: testrngfunc() - -> Result -(3 rows) - -select testrngfunc(); - testrngfunc ------------------ - (1.000000,2.00) - (3.000000,4.00) -(2 rows) - -explain (verbose, costs off) -select * from testrngfunc(); - QUERY PLAN ----------------------------------------------------------- - Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1" - -> Unique - Output: (1), (2) - -> Sort - Output: (1), (2) - Sort Key: (1), (2) - -> Append - -> Result - Output: 1, 2 - -> Result - Output: 3, 4 -(12 rows) - -select * from testrngfunc(); - f1 | f2 -----------+------ - 1.000000 | 2.00 - 3.000000 | 4.00 -(2 rows) - -drop type rngfunc_type cascade; -NOTICE: drop cascades to function testrngfunc() --- --- Check some cases involving added/dropped columns in a rowtype result --- -create temp table users (userid text, seq int, email text, todrop bool, moredrop int, enabled bool); -insert into users values ('id',1,'email',true,11,true); -insert into users values ('id2',2,'email2',true,12,true); -alter table users drop column todrop; -create or replace function get_first_user() returns users as -$$ SELECT * FROM users ORDER BY userid LIMIT 1; $$ -language sql stable; -SELECT get_first_user(); - get_first_user -------------------- - (id,1,email,11,t) -(1 row) - -SELECT * FROM get_first_user(); - userid | seq | email | moredrop | enabled ---------+-----+-------+----------+--------- - id | 1 | email | 11 | t -(1 row) - -create or replace function get_users() returns setof users as -$$ SELECT * FROM users ORDER BY userid; $$ -language sql stable; -SELECT get_users(); - get_users ---------------------- - (id,1,email,11,t) - (id2,2,email2,12,t) -(2 rows) - -SELECT * FROM get_users(); - userid | seq | email | moredrop | enabled ---------+-----+--------+----------+--------- - id | 1 | email | 11 | t - id2 | 2 | email2 | 12 | t -(2 rows) - -SELECT * FROM get_users() WITH ORDINALITY; -- make sure ordinality copes - userid | seq | email | moredrop | enabled | ordinality ---------+-----+--------+----------+---------+------------ - id | 1 | email | 11 | t | 1 - id2 | 2 | email2 | 12 | t | 2 -(2 rows) - --- multiple functions vs. dropped columns -SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY; - generate_series | userid | seq | email | moredrop | enabled | ordinality ------------------+--------+-----+--------+----------+---------+------------ - 10 | id | 1 | email | 11 | t | 1 - 11 | id2 | 2 | email2 | 12 | t | 2 -(2 rows) - -SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY; - userid | seq | email | moredrop | enabled | generate_series | ordinality ---------+-----+--------+----------+---------+-----------------+------------ - id | 1 | email | 11 | t | 10 | 1 - id2 | 2 | email2 | 12 | t | 11 | 2 -(2 rows) - --- check that we can cope with post-parsing changes in rowtypes -create temp view usersview as -SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY; -select * from usersview; - userid | seq | email | moredrop | enabled | generate_series | ordinality ---------+-----+--------+----------+---------+-----------------+------------ - id | 1 | email | 11 | t | 10 | 1 - id2 | 2 | email2 | 12 | t | 11 | 2 -(2 rows) - -alter table users add column junk text; -select * from usersview; - userid | seq | email | moredrop | enabled | generate_series | ordinality ---------+-----+--------+----------+---------+-----------------+------------ - id | 1 | email | 11 | t | 10 | 1 - id2 | 2 | email2 | 12 | t | 11 | 2 -(2 rows) - -begin; -alter table users drop column moredrop; -select * from usersview; -- expect clean failure -ERROR: attribute 5 of type record has been dropped -rollback; -alter table users alter column seq type numeric; -select * from usersview; -- expect clean failure -ERROR: attribute 2 of type record has wrong type -DETAIL: Table has type numeric, but query expects integer. -drop view usersview; -drop function get_first_user(); -drop function get_users(); -drop table users; --- check behavior with type coercion required for a set-op -create or replace function rngfuncbar() returns setof text as -$$ select 'foo'::varchar union all select 'bar'::varchar ; $$ -language sql stable; -select rngfuncbar(); - rngfuncbar ------------- - foo - bar -(2 rows) - -select * from rngfuncbar(); - rngfuncbar ------------- - foo - bar -(2 rows) - --- this function is now inlinable, too: -explain (verbose, costs off) select * from rngfuncbar(); - QUERY PLAN ------------------------------------------------- - Result - Output: ('foo'::character varying) - -> Append - -> Result - Output: 'foo'::character varying - -> Result - Output: 'bar'::character varying -(7 rows) - -drop function rngfuncbar(); --- check handling of a SQL function with multiple OUT params (bug #5777) -create or replace function rngfuncbar(out integer, out numeric) as -$$ select (1, 2.1) $$ language sql; -select * from rngfuncbar(); - column1 | column2 ----------+--------- - 1 | 2.1 -(1 row) - -create or replace function rngfuncbar(out integer, out numeric) as -$$ select (1, 2) $$ language sql; -select * from rngfuncbar(); -- fail -ERROR: function return row and query-specified return row do not match -DETAIL: Returned type integer at ordinal position 2, but query expects numeric. -create or replace function rngfuncbar(out integer, out numeric) as -$$ select (1, 2.1, 3) $$ language sql; -select * from rngfuncbar(); -- fail -ERROR: function return row and query-specified return row do not match -DETAIL: Returned row contains 3 attributes, but query expects 2. -drop function rngfuncbar(); --- check whole-row-Var handling in nested lateral functions (bug #11703) -create function extractq2(t int8_tbl) returns int8 as $$ - select t.q2 -$$ language sql immutable; -explain (verbose, costs off) -select x from int8_tbl, extractq2(int8_tbl) f(x); - QUERY PLAN ------------------------------------------- - Nested Loop - Output: f.x - -> Seq Scan on public.int8_tbl - Output: int8_tbl.q1, int8_tbl.q2 - -> Function Scan on f - Output: f.x - Function Call: int8_tbl.q2 -(7 rows) - -select x from int8_tbl, extractq2(int8_tbl) f(x); - x -------------------- - 456 - 4567890123456789 - 123 - 4567890123456789 - -4567890123456789 -(5 rows) - -create function extractq2_2(t int8_tbl) returns table(ret1 int8) as $$ - select extractq2(t) offset 0 -$$ language sql immutable; -explain (verbose, costs off) -select x from int8_tbl, extractq2_2(int8_tbl) f(x); - QUERY PLAN ------------------------------------ - Nested Loop - Output: ((int8_tbl.*).q2) - -> Seq Scan on public.int8_tbl - Output: int8_tbl.* - -> Result - Output: (int8_tbl.*).q2 -(6 rows) - -select x from int8_tbl, extractq2_2(int8_tbl) f(x); - x -------------------- - 456 - 4567890123456789 - 123 - 4567890123456789 - -4567890123456789 -(5 rows) - --- without the "offset 0", this function gets optimized quite differently -create function extractq2_2_opt(t int8_tbl) returns table(ret1 int8) as $$ - select extractq2(t) -$$ language sql immutable; -explain (verbose, costs off) -select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x); - QUERY PLAN ------------------------------ - Seq Scan on public.int8_tbl - Output: int8_tbl.q2 -(2 rows) - -select x from int8_tbl, extractq2_2_opt(int8_tbl) f(x); - x -------------------- - 456 - 4567890123456789 - 123 - 4567890123456789 - -4567890123456789 -(5 rows) - --- check handling of nulls in SRF results (bug #7808) -create type rngfunc2 as (a integer, b text); -select *, row_to_json(u) from unnest(array[(1,'foo')::rngfunc2, null::rngfunc2]) u; - a | b | row_to_json ----+-----+--------------------- - 1 | foo | {"a":1,"b":"foo"} - | | {"a":null,"b":null} -(2 rows) - -select *, row_to_json(u) from unnest(array[null::rngfunc2, null::rngfunc2]) u; - a | b | row_to_json ----+---+--------------------- - | | {"a":null,"b":null} - | | {"a":null,"b":null} -(2 rows) - -select *, row_to_json(u) from unnest(array[null::rngfunc2, (1,'foo')::rngfunc2, null::rngfunc2]) u; - a | b | row_to_json ----+-----+--------------------- - | | {"a":null,"b":null} - 1 | foo | {"a":1,"b":"foo"} - | | {"a":null,"b":null} -(3 rows) - -select *, row_to_json(u) from unnest(array[]::rngfunc2[]) u; - a | b | row_to_json ----+---+------------- -(0 rows) - -drop type rngfunc2; --- check handling of functions pulled up into function RTEs (bug #17227) -explain (verbose, costs off) -select * from - (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture - from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) - as unnested_modules(module)) as ss, - jsonb_to_recordset(ss.lecture) as j (id text); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------- - Nested Loop - Output: jsonb_path_query_array((unnested_modules.module -> 'lectures'::text), '$[*]'::jsonpath, '{}'::jsonb, false), j.id - -> Function Scan on pg_catalog.unnest unnested_modules - Output: unnested_modules.module - Function Call: unnest('{"{\"lectures\": [{\"id\": \"1\"}]}"}'::jsonb[]) - -> Function Scan on pg_catalog.jsonb_to_recordset j - Output: j.id - Function Call: jsonb_to_recordset(jsonb_path_query_array((unnested_modules.module -> 'lectures'::text), '$[*]'::jsonpath, '{}'::jsonb, false)) -(8 rows) - -select * from - (select jsonb_path_query_array(module->'lectures', '$[*]') as lecture - from unnest(array['{"lectures": [{"id": "1"}]}'::jsonb]) - as unnested_modules(module)) as ss, - jsonb_to_recordset(ss.lecture) as j (id text); - lecture | id ----------------+---- - [{"id": "1"}] | 1 -(1 row) - +FATAL: fatal llvm error: CPU 'generic' is not supported. Use generic-rv64 +server closed the connection unexpectedly + This probably means the server terminated abnormally + before or while processing the request. +connection to server was lost diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/alter_table.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/alter_table.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/alter_table.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/alter_table.out 2022-02-13 01:13:25.888955121 +0100 @@ -3974,6 +3974,7 @@ a int, b int ) PARTITION BY RANGE (a, b); +ERROR: relation "range_parted" already exists -- check that violating rows are correctly reported CREATE TABLE part1 ( a int NOT NULL CHECK (a = 1), @@ -3982,10 +3983,11 @@ INSERT INTO part1 VALUES (1, 10); -- Remember the TO bound is exclusive ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10); -ERROR: partition constraint of relation "part1" is violated by some row +ERROR: child table "part1" has different type for column "a" -- should be ok after deleting the bad row DELETE FROM part1; ALTER TABLE range_parted ATTACH PARTITION part1 FOR VALUES FROM (1, 1) TO (1, 10); +ERROR: child table "part1" has different type for column "a" -- adding constraints that describe the desired partition constraint -- (or more restrictive) will help skip the validation scan CREATE TABLE part2 ( @@ -3993,6 +3995,7 @@ b int NOT NULL CHECK (b >= 10 AND b < 18) ); ALTER TABLE range_parted ATTACH PARTITION part2 FOR VALUES FROM (1, 10) TO (1, 20); +ERROR: child table "part2" has different type for column "a" -- Create default partition CREATE TABLE partr_def1 PARTITION OF range_parted DEFAULT; -- Only one default partition is allowed, hence, following should give error @@ -4283,6 +4286,9 @@ -- cleanup DROP TABLE list_parted, list_parted2, range_parted; +ERROR: cannot drop desired object(s) because other objects depend on them +DETAIL: view upview depends on table range_parted +HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP TABLE fail_def_part; DROP TABLE hash_parted; -- more tests for certain multi-level partitioning scenarios diff -U3 /build/postgresql/src/postgresql-13.5/src/test/regress/expected/with.out /build/postgresql/src/postgresql-13.5/src/test/regress/results/with.out --- /build/postgresql/src/postgresql-13.5/src/test/regress/expected/with.out 2022-02-13 00:42:43.000000000 +0100 +++ /build/postgresql/src/postgresql-13.5/src/test/regress/results/with.out 2022-02-13 01:13:23.648951341 +0100 @@ -487,1924 +487,8 @@ select * from x) ) select * from q limit 32; - id | parent_department | name -----+-------------------+------ - 0 | | ROOT - 1 | 0 | A - 2 | 1 | B - 3 | 2 | C - 4 | 2 | D - 5 | 0 | E - 6 | 4 | F - 7 | 5 | G - 0 | | ROOT - 1 | 0 | A - 2 | 1 | B - 3 | 2 | C - 4 | 2 | D - 5 | 0 | E - 6 | 4 | F - 7 | 5 | G - 0 | | ROOT - 1 | 0 | A - 2 | 1 | B - 3 | 2 | C - 4 | 2 | D - 5 | 0 | E - 6 | 4 | F - 7 | 5 | G - 0 | | ROOT - 1 | 0 | A - 2 | 1 | B - 3 | 2 | C - 4 | 2 | D - 5 | 0 | E - 6 | 4 | F - 7 | 5 | G -(32 rows) - --- recursive term has sub-UNION -WITH RECURSIVE t(i,j) AS ( - VALUES (1,2) - UNION ALL - SELECT t2.i, t.j+1 FROM - (SELECT 2 AS i UNION ALL SELECT 3 AS i) AS t2 - JOIN t ON (t2.i = t.i+1)) - SELECT * FROM t; - i | j ----+--- - 1 | 2 - 2 | 3 - 3 | 4 -(3 rows) - --- --- different tree example --- -CREATE TEMPORARY TABLE tree( - id INTEGER PRIMARY KEY, - parent_id INTEGER REFERENCES tree(id) -); -INSERT INTO tree -VALUES (1, NULL), (2, 1), (3,1), (4,2), (5,2), (6,2), (7,3), (8,3), - (9,4), (10,4), (11,7), (12,7), (13,7), (14, 9), (15,11), (16,11); --- --- get all paths from "second level" nodes to leaf nodes --- -WITH RECURSIVE t(id, path) AS ( - VALUES(1,ARRAY[]::integer[]) -UNION ALL - SELECT tree.id, t.path || tree.id - FROM tree JOIN t ON (tree.parent_id = t.id) -) -SELECT t1.*, t2.* FROM t AS t1 JOIN t AS t2 ON - (t1.path[1] = t2.path[1] AND - array_upper(t1.path,1) = 1 AND - array_upper(t2.path,1) > 1) - ORDER BY t1.id, t2.id; - id | path | id | path -----+------+----+------------- - 2 | {2} | 4 | {2,4} - 2 | {2} | 5 | {2,5} - 2 | {2} | 6 | {2,6} - 2 | {2} | 9 | {2,4,9} - 2 | {2} | 10 | {2,4,10} - 2 | {2} | 14 | {2,4,9,14} - 3 | {3} | 7 | {3,7} - 3 | {3} | 8 | {3,8} - 3 | {3} | 11 | {3,7,11} - 3 | {3} | 12 | {3,7,12} - 3 | {3} | 13 | {3,7,13} - 3 | {3} | 15 | {3,7,11,15} - 3 | {3} | 16 | {3,7,11,16} -(13 rows) - --- just count 'em -WITH RECURSIVE t(id, path) AS ( - VALUES(1,ARRAY[]::integer[]) -UNION ALL - SELECT tree.id, t.path || tree.id - FROM tree JOIN t ON (tree.parent_id = t.id) -) -SELECT t1.id, count(t2.*) FROM t AS t1 JOIN t AS t2 ON - (t1.path[1] = t2.path[1] AND - array_upper(t1.path,1) = 1 AND - array_upper(t2.path,1) > 1) - GROUP BY t1.id - ORDER BY t1.id; - id | count -----+------- - 2 | 6 - 3 | 7 -(2 rows) - --- this variant tickled a whole-row-variable bug in 8.4devel -WITH RECURSIVE t(id, path) AS ( - VALUES(1,ARRAY[]::integer[]) -UNION ALL - SELECT tree.id, t.path || tree.id - FROM tree JOIN t ON (tree.parent_id = t.id) -) -SELECT t1.id, t2.path, t2 FROM t AS t1 JOIN t AS t2 ON -(t1.id=t2.id); - id | path | t2 -----+-------------+-------------------- - 1 | {} | (1,{}) - 2 | {2} | (2,{2}) - 3 | {3} | (3,{3}) - 4 | {2,4} | (4,"{2,4}") - 5 | {2,5} | (5,"{2,5}") - 6 | {2,6} | (6,"{2,6}") - 7 | {3,7} | (7,"{3,7}") - 8 | {3,8} | (8,"{3,8}") - 9 | {2,4,9} | (9,"{2,4,9}") - 10 | {2,4,10} | (10,"{2,4,10}") - 11 | {3,7,11} | (11,"{3,7,11}") - 12 | {3,7,12} | (12,"{3,7,12}") - 13 | {3,7,13} | (13,"{3,7,13}") - 14 | {2,4,9,14} | (14,"{2,4,9,14}") - 15 | {3,7,11,15} | (15,"{3,7,11,15}") - 16 | {3,7,11,16} | (16,"{3,7,11,16}") -(16 rows) - --- --- test cycle detection --- -create temp table graph( f int, t int, label text ); -insert into graph values - (1, 2, 'arc 1 -> 2'), - (1, 3, 'arc 1 -> 3'), - (2, 3, 'arc 2 -> 3'), - (1, 4, 'arc 1 -> 4'), - (4, 5, 'arc 4 -> 5'), - (5, 1, 'arc 5 -> 1'); -with recursive search_graph(f, t, label, path, cycle) as ( - select *, array[row(g.f, g.t)], false from graph g - union all - select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path) - from graph g, search_graph sg - where g.f = sg.t and not cycle -) -select * from search_graph; - f | t | label | path | cycle ----+---+------------+-------------------------------------------+------- - 1 | 2 | arc 1 -> 2 | {"(1,2)"} | f - 1 | 3 | arc 1 -> 3 | {"(1,3)"} | f - 2 | 3 | arc 2 -> 3 | {"(2,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(1,4)"} | f - 4 | 5 | arc 4 -> 5 | {"(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"} | f - 1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"} | f - 2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"} | f - 4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"} | f - 1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"} | f - 2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"} | f - 4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"} | f - 1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"} | t - 2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"} | f - 4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"} | t - 5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"} | t - 2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f -(25 rows) - --- ordering by the path column has same effect as SEARCH DEPTH FIRST -with recursive search_graph(f, t, label, path, cycle) as ( - select *, array[row(g.f, g.t)], false from graph g - union all - select g.*, path || row(g.f, g.t), row(g.f, g.t) = any(path) - from graph g, search_graph sg - where g.f = sg.t and not cycle -) -select * from search_graph order by path; - f | t | label | path | cycle ----+---+------------+-------------------------------------------+------- - 1 | 2 | arc 1 -> 2 | {"(1,2)"} | f - 2 | 3 | arc 2 -> 3 | {"(1,2)","(2,3)"} | f - 1 | 3 | arc 1 -> 3 | {"(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(1,4)"} | f - 4 | 5 | arc 4 -> 5 | {"(1,4)","(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(1,4)","(4,5)","(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(1,4)","(4,5)","(5,1)","(1,2)"} | f - 2 | 3 | arc 2 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,2)","(2,3)"} | f - 1 | 3 | arc 1 -> 3 | {"(1,4)","(4,5)","(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(1,4)","(4,5)","(5,1)","(1,4)"} | t - 2 | 3 | arc 2 -> 3 | {"(2,3)"} | f - 4 | 5 | arc 4 -> 5 | {"(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(4,5)","(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(4,5)","(5,1)","(1,2)"} | f - 2 | 3 | arc 2 -> 3 | {"(4,5)","(5,1)","(1,2)","(2,3)"} | f - 1 | 3 | arc 1 -> 3 | {"(4,5)","(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(4,5)","(5,1)","(1,4)"} | f - 4 | 5 | arc 4 -> 5 | {"(4,5)","(5,1)","(1,4)","(4,5)"} | t - 5 | 1 | arc 5 -> 1 | {"(5,1)"} | f - 1 | 2 | arc 1 -> 2 | {"(5,1)","(1,2)"} | f - 2 | 3 | arc 2 -> 3 | {"(5,1)","(1,2)","(2,3)"} | f - 1 | 3 | arc 1 -> 3 | {"(5,1)","(1,3)"} | f - 1 | 4 | arc 1 -> 4 | {"(5,1)","(1,4)"} | f - 4 | 5 | arc 4 -> 5 | {"(5,1)","(1,4)","(4,5)"} | f - 5 | 1 | arc 5 -> 1 | {"(5,1)","(1,4)","(4,5)","(5,1)"} | t -(25 rows) - --- --- test multiple WITH queries --- -WITH RECURSIVE - y (id) AS (VALUES (1)), - x (id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5) -SELECT * FROM x; - id ----- - 1 - 2 - 3 - 4 - 5 -(5 rows) - --- forward reference OK -WITH RECURSIVE - x(id) AS (SELECT * FROM y UNION ALL SELECT id+1 FROM x WHERE id < 5), - y(id) AS (values (1)) - SELECT * FROM x; - id ----- - 1 - 2 - 3 - 4 - 5 -(5 rows) - -WITH RECURSIVE - x(id) AS - (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5), - y(id) AS - (VALUES (1) UNION ALL SELECT id+1 FROM y WHERE id < 10) - SELECT y.*, x.* FROM y LEFT JOIN x USING (id); - id | id -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | - 7 | - 8 | - 9 | - 10 | -(10 rows) - -WITH RECURSIVE - x(id) AS - (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 5), - y(id) AS - (VALUES (1) UNION ALL SELECT id+1 FROM x WHERE id < 10) - SELECT y.*, x.* FROM y LEFT JOIN x USING (id); - id | id -----+---- - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | -(6 rows) - -WITH RECURSIVE - x(id) AS - (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ), - y(id) AS - (SELECT * FROM x UNION ALL SELECT * FROM x), - z(id) AS - (SELECT * FROM x UNION ALL SELECT id+1 FROM z WHERE id < 10) - SELECT * FROM z; - id ----- - 1 - 2 - 3 - 2 - 3 - 4 - 3 - 4 - 5 - 4 - 5 - 6 - 5 - 6 - 7 - 6 - 7 - 8 - 7 - 8 - 9 - 8 - 9 - 10 - 9 - 10 - 10 -(27 rows) - -WITH RECURSIVE - x(id) AS - (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 3 ), - y(id) AS - (SELECT * FROM x UNION ALL SELECT * FROM x), - z(id) AS - (SELECT * FROM y UNION ALL SELECT id+1 FROM z WHERE id < 10) - SELECT * FROM z; - id ----- - 1 - 2 - 3 - 1 - 2 - 3 - 2 - 3 - 4 - 2 - 3 - 4 - 3 - 4 - 5 - 3 - 4 - 5 - 4 - 5 - 6 - 4 - 5 - 6 - 5 - 6 - 7 - 5 - 6 - 7 - 6 - 7 - 8 - 6 - 7 - 8 - 7 - 8 - 9 - 7 - 8 - 9 - 8 - 9 - 10 - 8 - 9 - 10 - 9 - 10 - 9 - 10 - 10 - 10 -(54 rows) - --- --- Test WITH attached to a data-modifying statement --- -CREATE TEMPORARY TABLE y (a INTEGER); -INSERT INTO y SELECT generate_series(1, 10); -WITH t AS ( - SELECT a FROM y -) -INSERT INTO y -SELECT a+20 FROM t RETURNING *; - a ----- - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 -(10 rows) - -SELECT * FROM y; - a ----- - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 21 - 22 - 23 - 24 - 25 - 26 - 27 - 28 - 29 - 30 -(20 rows) - -WITH t AS ( - SELECT a FROM y -) -UPDATE y SET a = y.a-10 FROM t WHERE y.a > 20 AND t.a = y.a RETURNING y.a; - a ----- - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 -(10 rows) - -SELECT * FROM y; - a ----- - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 -(20 rows) - -WITH RECURSIVE t(a) AS ( - SELECT 11 - UNION ALL - SELECT a+1 FROM t WHERE a < 50 -) -DELETE FROM y USING t WHERE t.a = y.a RETURNING y.a; - a ----- - 11 - 12 - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 -(10 rows) - -SELECT * FROM y; - a ----- - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 -(10 rows) - -DROP TABLE y; --- --- error cases --- --- INTERSECT -WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x) - SELECT * FROM x; -ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT SELECT n+1 FROM x... - ^ -WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FROM x) - SELECT * FROM x; -ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 INTERSECT ALL SELECT n+1 FR... - ^ --- EXCEPT -WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) - SELECT * FROM x; -ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT SELECT n+1 FROM x) - ^ -WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM x) - SELECT * FROM x; -ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 EXCEPT ALL SELECT n+1 FROM ... - ^ --- no non-recursive term -WITH RECURSIVE x(n) AS (SELECT n FROM x) - SELECT * FROM x; -ERROR: recursive query "x" does not have the form non-recursive-term UNION [ALL] recursive-term -LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x) - ^ --- recursive term in the left hand side (strictly speaking, should allow this) -WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1) - SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within its non-recursive term -LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1) - ^ -CREATE TEMPORARY TABLE y (a INTEGER); -INSERT INTO y SELECT generate_series(1, 10); --- LEFT JOIN -WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 - UNION ALL - SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10) -SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within an outer join -LINE 3: SELECT x.n+1 FROM y LEFT JOIN x ON x.n = y.a WHERE n < 10) - ^ --- RIGHT JOIN -WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 - UNION ALL - SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10) -SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within an outer join -LINE 3: SELECT x.n+1 FROM x RIGHT JOIN y ON x.n = y.a WHERE n < 10) - ^ --- FULL JOIN -WITH RECURSIVE x(n) AS (SELECT a FROM y WHERE a = 1 - UNION ALL - SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10) -SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within an outer join -LINE 3: SELECT x.n+1 FROM x FULL JOIN y ON x.n = y.a WHERE n < 10) - ^ --- subquery -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x - WHERE n IN (SELECT * FROM x)) - SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within a subquery -LINE 2: WHERE n IN (SELECT * FROM x)) - ^ --- aggregate functions -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) FROM x) - SELECT * FROM x; -ERROR: aggregate functions are not allowed in a recursive query's recursive term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT count(*) F... - ^ -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FROM x) - SELECT * FROM x; -ERROR: aggregate functions are not allowed in a recursive query's recursive term -LINE 1: WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT sum(n) FRO... - ^ --- ORDER BY -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) - SELECT * FROM x; -ERROR: ORDER BY in a recursive query is not implemented -LINE 1: ...VE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x ORDER BY 1) - ^ --- LIMIT/OFFSET -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) - SELECT * FROM x; -ERROR: OFFSET in a recursive query is not implemented -LINE 1: ... AS (SELECT 1 UNION ALL SELECT n+1 FROM x LIMIT 10 OFFSET 1) - ^ --- FOR UPDATE -WITH RECURSIVE x(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM x FOR UPDATE) - SELECT * FROM x; -ERROR: FOR UPDATE/SHARE in a recursive query is not implemented --- target list has a recursive query name -WITH RECURSIVE x(id) AS (values (1) - UNION ALL - SELECT (SELECT * FROM x) FROM x WHERE id < 5 -) SELECT * FROM x; -ERROR: recursive reference to query "x" must not appear within a subquery -LINE 3: SELECT (SELECT * FROM x) FROM x WHERE id < 5 - ^ --- mutual recursive query (not implemented) -WITH RECURSIVE - x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id < 5), - y (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM x WHERE id < 5) -SELECT * FROM x; -ERROR: mutual recursion between WITH items is not implemented -LINE 2: x (id) AS (SELECT 1 UNION ALL SELECT id+1 FROM y WHERE id ... - ^ --- non-linear recursion is not allowed -WITH RECURSIVE foo(i) AS - (values (1) - UNION ALL - (SELECT i+1 FROM foo WHERE i < 10 - UNION ALL - SELECT i+1 FROM foo WHERE i < 5) -) SELECT * FROM foo; -ERROR: recursive reference to query "foo" must not appear more than once -LINE 6: SELECT i+1 FROM foo WHERE i < 5) - ^ -WITH RECURSIVE foo(i) AS - (values (1) - UNION ALL - SELECT * FROM - (SELECT i+1 FROM foo WHERE i < 10 - UNION ALL - SELECT i+1 FROM foo WHERE i < 5) AS t -) SELECT * FROM foo; -ERROR: recursive reference to query "foo" must not appear more than once -LINE 7: SELECT i+1 FROM foo WHERE i < 5) AS t - ^ -WITH RECURSIVE foo(i) AS - (values (1) - UNION ALL - (SELECT i+1 FROM foo WHERE i < 10 - EXCEPT - SELECT i+1 FROM foo WHERE i < 5) -) SELECT * FROM foo; -ERROR: recursive reference to query "foo" must not appear within EXCEPT -LINE 6: SELECT i+1 FROM foo WHERE i < 5) - ^ -WITH RECURSIVE foo(i) AS - (values (1) - UNION ALL - (SELECT i+1 FROM foo WHERE i < 10 - INTERSECT - SELECT i+1 FROM foo WHERE i < 5) -) SELECT * FROM foo; -ERROR: recursive reference to query "foo" must not appear more than once -LINE 6: SELECT i+1 FROM foo WHERE i < 5) - ^ --- Wrong type induced from non-recursive term -WITH RECURSIVE foo(i) AS - (SELECT i FROM (VALUES(1),(2)) t(i) - UNION ALL - SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10) -SELECT * FROM foo; -ERROR: recursive query "foo" column 1 has type integer in non-recursive term but type numeric overall -LINE 2: (SELECT i FROM (VALUES(1),(2)) t(i) - ^ -HINT: Cast the output of the non-recursive term to the correct type. --- rejects different typmod, too (should we allow this?) -WITH RECURSIVE foo(i) AS - (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i) - UNION ALL - SELECT (i+1)::numeric(10,0) FROM foo WHERE i < 10) -SELECT * FROM foo; -ERROR: recursive query "foo" column 1 has type numeric(3,0) in non-recursive term but type numeric overall -LINE 2: (SELECT i::numeric(3,0) FROM (VALUES(1),(2)) t(i) - ^ -HINT: Cast the output of the non-recursive term to the correct type. --- disallow OLD/NEW reference in CTE -CREATE TEMPORARY TABLE x (n integer); -CREATE RULE r2 AS ON UPDATE TO x DO INSTEAD - WITH t AS (SELECT OLD.*) UPDATE y SET a = t.n FROM t; -ERROR: cannot refer to OLD within WITH query --- --- test for bug #4902 --- -with cte(foo) as ( values(42) ) values((select foo from cte)); - column1 ---------- - 42 -(1 row) - -with cte(foo) as ( select 42 ) select * from ((select foo from cte)) q; - foo ------ - 42 -(1 row) - --- test CTE referencing an outer-level variable (to see that changed-parameter --- signaling still works properly after fixing this bug) -select ( with cte(foo) as ( values(f1) ) - select (select foo from cte) ) -from int4_tbl; - foo -------------- - 0 - 123456 - -123456 - 2147483647 - -2147483647 -(5 rows) - -select ( with cte(foo) as ( values(f1) ) - values((select foo from cte)) ) -from int4_tbl; - column1 -------------- - 0 - 123456 - -123456 - 2147483647 - -2147483647 -(5 rows) - --- --- test for nested-recursive-WITH bug --- -WITH RECURSIVE t(j) AS ( - WITH RECURSIVE s(i) AS ( - VALUES (1) - UNION ALL - SELECT i+1 FROM s WHERE i < 10 - ) - SELECT i FROM s - UNION ALL - SELECT j+1 FROM t WHERE j < 10 -) -SELECT * FROM t; - j ----- - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 5 - 6 - 7 - 8 - 9 - 10 - 6 - 7 - 8 - 9 - 10 - 7 - 8 - 9 - 10 - 8 - 9 - 10 - 9 - 10 - 10 -(55 rows) - --- --- test WITH attached to intermediate-level set operation --- -WITH outermost(x) AS ( - SELECT 1 - UNION (WITH innermost as (SELECT 2) - SELECT * FROM innermost - UNION SELECT 3) -) -SELECT * FROM outermost ORDER BY 1; - x ---- - 1 - 2 - 3 -(3 rows) - -WITH outermost(x) AS ( - SELECT 1 - UNION (WITH innermost as (SELECT 2) - SELECT * FROM outermost -- fail - UNION SELECT * FROM innermost) -) -SELECT * FROM outermost ORDER BY 1; -ERROR: relation "outermost" does not exist -LINE 4: SELECT * FROM outermost - ^ -DETAIL: There is a WITH item named "outermost", but it cannot be referenced from this part of the query. -HINT: Use WITH RECURSIVE, or re-order the WITH items to remove forward references. -WITH RECURSIVE outermost(x) AS ( - SELECT 1 - UNION (WITH innermost as (SELECT 2) - SELECT * FROM outermost - UNION SELECT * FROM innermost) -) -SELECT * FROM outermost ORDER BY 1; - x ---- - 1 - 2 -(2 rows) - -WITH RECURSIVE outermost(x) AS ( - WITH innermost as (SELECT 2 FROM outermost) -- fail - SELECT * FROM innermost - UNION SELECT * from outermost -) -SELECT * FROM outermost ORDER BY 1; -ERROR: recursive reference to query "outermost" must not appear within a subquery -LINE 2: WITH innermost as (SELECT 2 FROM outermost) - ^ --- --- This test will fail with the old implementation of PARAM_EXEC parameter --- assignment, because the "q1" Var passed down to A's targetlist subselect --- looks exactly like the "A.id" Var passed down to C's subselect, causing --- the old code to give them the same runtime PARAM_EXEC slot. But the --- lifespans of the two parameters overlap, thanks to B also reading A. --- -with -A as ( select q2 as id, (select q1) as x from int8_tbl ), -B as ( select id, row_number() over (partition by id) as r from A ), -C as ( select A.id, array(select B.id from B where B.id = A.id) from A ) -select * from C; - id | array --------------------+------------------------------------- - 456 | {456} - 4567890123456789 | {4567890123456789,4567890123456789} - 123 | {123} - 4567890123456789 | {4567890123456789,4567890123456789} - -4567890123456789 | {-4567890123456789} -(5 rows) - --- --- Test CTEs read in non-initialization orders --- -WITH RECURSIVE - tab(id_key,link) AS (VALUES (1,17), (2,17), (3,17), (4,17), (6,17), (5,17)), - iter (id_key, row_type, link) AS ( - SELECT 0, 'base', 17 - UNION ALL ( - WITH remaining(id_key, row_type, link, min) AS ( - SELECT tab.id_key, 'true'::text, iter.link, MIN(tab.id_key) OVER () - FROM tab INNER JOIN iter USING (link) - WHERE tab.id_key > iter.id_key - ), - first_remaining AS ( - SELECT id_key, row_type, link - FROM remaining - WHERE id_key=min - ), - effect AS ( - SELECT tab.id_key, 'new'::text, tab.link - FROM first_remaining e INNER JOIN tab ON e.id_key=tab.id_key - WHERE e.row_type = 'false' - ) -